PostgreSQL Source Code git master
sql-sqlda.c File Reference
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "ecpg_config.h"
#include "sqlda-native.h"
#include <pgtypes.h>
Include dependency graph for sql-sqlda.c:

Go to the source code of this file.

Data Structures

struct  numeric
 
struct  decimal
 

Macros

#define ECPGdebug(X, Y)   ECPGdebug((X)+100,(Y))
 
#define ECPG_SQLDA_H
 
#define PGTYPES_NUMERIC
 
#define NUMERIC_POS   0x0000
 
#define NUMERIC_NEG   0x4000
 
#define NUMERIC_NAN   0xC000
 
#define NUMERIC_NULL   0xF000
 
#define NUMERIC_MAX_PRECISION   1000
 
#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION
 
#define NUMERIC_MIN_DISPLAY_SCALE   0
 
#define NUMERIC_MIN_SIG_DIGITS   16
 
#define DECSIZE   30
 

Typedefs

typedef struct sqlvar_struct sqlvar_t
 
typedef struct sqlda_struct sqlda_t
 
typedef unsigned char NumericDigit
 

Functions

numericPGTYPESnumeric_new (void)
 
decimalPGTYPESdecimal_new (void)
 
void PGTYPESnumeric_free (numeric *var)
 
void PGTYPESdecimal_free (decimal *var)
 
numericPGTYPESnumeric_from_asc (char *str, char **endptr)
 
char * PGTYPESnumeric_to_asc (numeric *num, int dscale)
 
int PGTYPESnumeric_add (numeric *var1, numeric *var2, numeric *result)
 
int PGTYPESnumeric_sub (numeric *var1, numeric *var2, numeric *result)
 
int PGTYPESnumeric_mul (numeric *var1, numeric *var2, numeric *result)
 
int PGTYPESnumeric_div (numeric *var1, numeric *var2, numeric *result)
 
int PGTYPESnumeric_cmp (numeric *var1, numeric *var2)
 
int PGTYPESnumeric_from_int (signed int int_val, numeric *var)
 
int PGTYPESnumeric_from_long (signed long int long_val, numeric *var)
 
int PGTYPESnumeric_copy (numeric *src, numeric *dst)
 
int PGTYPESnumeric_from_double (double d, numeric *dst)
 
int PGTYPESnumeric_to_double (numeric *nv, double *dp)
 
int PGTYPESnumeric_to_int (numeric *nv, int *ip)
 
int PGTYPESnumeric_to_long (numeric *nv, long *lp)
 
int PGTYPESnumeric_to_decimal (numeric *src, decimal *dst)
 
int PGTYPESnumeric_from_decimal (decimal *src, numeric *dst)
 
static void dump_sqlda (sqlda_t *sqlda)
 
int main (void)
 

Variables

sqlda_tinp_sqlda
 
sqlda_toutp_sqlda
 
sqlda_toutp_sqlda1
 

Macro Definition Documentation

◆ DECSIZE

#define DECSIZE   30

Definition at line 64 of file sql-sqlda.c.

◆ ECPG_SQLDA_H

#define ECPG_SQLDA_H

Definition at line 28 of file sql-sqlda.c.

◆ ECPGdebug

#define ECPGdebug (   X,
 
)    ECPGdebug((X)+100,(Y))

Definition at line 7 of file sql-sqlda.c.

◆ NUMERIC_MAX_DISPLAY_SCALE

#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION

Definition at line 60 of file sql-sqlda.c.

◆ NUMERIC_MAX_PRECISION

#define NUMERIC_MAX_PRECISION   1000

Definition at line 59 of file sql-sqlda.c.

◆ NUMERIC_MIN_DISPLAY_SCALE

#define NUMERIC_MIN_DISPLAY_SCALE   0

Definition at line 61 of file sql-sqlda.c.

◆ NUMERIC_MIN_SIG_DIGITS

#define NUMERIC_MIN_SIG_DIGITS   16

Definition at line 62 of file sql-sqlda.c.

◆ NUMERIC_NAN

#define NUMERIC_NAN   0xC000

Definition at line 57 of file sql-sqlda.c.

◆ NUMERIC_NEG

#define NUMERIC_NEG   0x4000

Definition at line 56 of file sql-sqlda.c.

◆ NUMERIC_NULL

#define NUMERIC_NULL   0xF000

Definition at line 58 of file sql-sqlda.c.

◆ NUMERIC_POS

#define NUMERIC_POS   0x0000

Definition at line 55 of file sql-sqlda.c.

◆ PGTYPES_NUMERIC

#define PGTYPES_NUMERIC

Definition at line 51 of file sql-sqlda.c.

Typedef Documentation

◆ NumericDigit

typedef unsigned char NumericDigit

Definition at line 66 of file sql-sqlda.c.

◆ sqlda_t

typedef struct sqlda_struct sqlda_t

Definition at line 40 of file sql-sqlda.c.

◆ sqlvar_t

typedef struct sqlvar_struct sqlvar_t

Definition at line 39 of file sql-sqlda.c.

Function Documentation

◆ dump_sqlda()

static void dump_sqlda ( sqlda_t sqlda)
static

Definition at line 131 of file sql-sqlda.c.

132{
133 int i;
134
135 if (sqlda == NULL)
136 {
137 printf("dump_sqlda called with NULL sqlda\n");
138 return;
139 }
140
141 for (i = 0; i < sqlda->sqld; i++)
142 {
143 if (sqlda->sqlvar[i].sqlind && *(sqlda->sqlvar[i].sqlind) == -1)
144 printf("name sqlda descriptor: '%s' value NULL'\n", sqlda->sqlvar[i].sqlname.data);
145 else
146 switch (sqlda->sqlvar[i].sqltype)
147 {
148 case ECPGt_char:
149 printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname.data, sqlda->sqlvar[i].sqldata);
150 break;
151 case ECPGt_int:
152 printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname.data, *(int *)sqlda->sqlvar[i].sqldata);
153 break;
154 case ECPGt_long:
155 printf("name sqlda descriptor: '%s' value %ld\n", sqlda->sqlvar[i].sqlname.data, *(long int *)sqlda->sqlvar[i].sqldata);
156 break;
157 case ECPGt_long_long:
158 printf("name sqlda descriptor: '%s' value %lld\n",
159 sqlda->sqlvar[i].sqlname.data, *(long long int *)sqlda->sqlvar[i].sqldata);
160 break;
161 case ECPGt_double:
162 printf("name sqlda descriptor: '%s' value %f\n", sqlda->sqlvar[i].sqlname.data, *(double *)sqlda->sqlvar[i].sqldata);
163 break;
164 case ECPGt_numeric:
165 {
166 char *val;
167
169 printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val);
171 break;
172 }
173 }
174 }
175}
@ ECPGt_long_long
Definition: ecpgtype.h:45
@ ECPGt_numeric
Definition: ecpgtype.h:49
@ ECPGt_int
Definition: ecpgtype.h:44
@ ECPGt_long
Definition: ecpgtype.h:44
@ ECPGt_double
Definition: ecpgtype.h:47
@ ECPGt_char
Definition: ecpgtype.h:43
long val
Definition: informix.c:689
int i
Definition: isn.c:72
void PGTYPESchar_free(char *ptr)
Definition: common.c:145
#define printf(...)
Definition: port.h:245
char * PGTYPESnumeric_to_asc(numeric *num, int dscale)
Definition: numeric.c:343
struct sqlvar_struct sqlvar[1]
Definition: sqlda-native.h:40
char data[NAMEDATALEN]
Definition: sqlda-native.h:21
struct sqlname sqlname
Definition: sqlda-native.h:30
char * sqldata
Definition: sqlda-native.h:28
short * sqlind
Definition: sqlda-native.h:29

References sqlname::data, ECPGt_char, ECPGt_double, ECPGt_int, ECPGt_long, ECPGt_long_long, ECPGt_numeric, i, PGTYPESchar_free(), PGTYPESnumeric_to_asc(), printf, sqlda_struct::sqld, sqlvar_struct::sqldata, sqlvar_struct::sqlind, sqlvar_struct::sqlname, sqlvar_struct::sqltype, sqlda_struct::sqlvar, and val.

Referenced by main().

◆ main()

int main ( void  )

Definition at line 178 of file sql-sqlda.c.

179{
180/* exec sql begin declare section */
181
182
183
184
185
186#line 66 "sqlda.pgc"
187 char * stmt1 = "SELECT * FROM t1" ;
188
189#line 67 "sqlda.pgc"
190 char * stmt2 = "SELECT * FROM t1 WHERE id = ?" ;
191
192#line 68 "sqlda.pgc"
193 int rec ;
194
195#line 69 "sqlda.pgc"
196 int id ;
197/* exec sql end declare section */
198#line 70 "sqlda.pgc"
199
200
201 char msg[128];
202
203 ECPGdebug(1, stderr);
204
205 strcpy(msg, "connect");
206 { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , "regress1", 0);
207#line 77 "sqlda.pgc"
208
209if (sqlca.sqlcode < 0) exit (1);}
210#line 77 "sqlda.pgc"
211
212
213 strcpy(msg, "set");
214 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
215#line 80 "sqlda.pgc"
216
217if (sqlca.sqlcode < 0) exit (1);}
218#line 80 "sqlda.pgc"
219
220
221 strcpy(msg, "create");
222 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) , big bigint )", ECPGt_EOIT, ECPGt_EORT);
223#line 90 "sqlda.pgc"
224
225if (sqlca.sqlcode < 0) exit (1);}
226#line 90 "sqlda.pgc"
227
228
229 strcpy(msg, "insert");
230 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' , 1111111111111111111 ) , ( 2 , null , null , null , null , null ) , ( 3 , 'c' , 0.0 , 3 , 'c' , 3333333333333333333 ) , ( 4 , 'd' , 'NaN' , 4 , 'd' , 4444444444444444444 ) , ( 5 , 'e' , 0.001234 , 5 , 'e' , 5555555555555555555 )", ECPGt_EOIT, ECPGt_EORT);
231#line 98 "sqlda.pgc"
232
233if (sqlca.sqlcode < 0) exit (1);}
234#line 98 "sqlda.pgc"
235
236
237 strcpy(msg, "commit");
238 { ECPGtrans(__LINE__, NULL, "commit");
239#line 101 "sqlda.pgc"
240
241if (sqlca.sqlcode < 0) exit (1);}
242#line 101 "sqlda.pgc"
243
244
245 /* SQLDA test for getting all records from a table */
246
247 outp_sqlda = NULL;
248
249 strcpy(msg, "prepare");
250 { ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
251#line 108 "sqlda.pgc"
252
253if (sqlca.sqlcode < 0) exit (1);}
254#line 108 "sqlda.pgc"
255
256
257 strcpy(msg, "declare");
258 /* declare mycur1 cursor for $1 */
259#line 111 "sqlda.pgc"
260
261
262 strcpy(msg, "open");
263 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1",
264 ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
265 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
266#line 114 "sqlda.pgc"
267
268if (sqlca.sqlcode < 0) exit (1);}
269#line 114 "sqlda.pgc"
270
271
272 /* exec sql whenever not found break ; */
273#line 116 "sqlda.pgc"
274
275
276 rec = 0;
277 while (1)
278 {
279 strcpy(msg, "fetch");
280 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT,
281 ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L,
282 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
283#line 122 "sqlda.pgc"
284
285if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
286#line 122 "sqlda.pgc"
287
288if (sqlca.sqlcode < 0) exit (1);}
289#line 122 "sqlda.pgc"
290
291
292 printf("FETCH RECORD %d\n", ++rec);
294 }
295
296 /* exec sql whenever not found continue ; */
297#line 128 "sqlda.pgc"
298
299
300 strcpy(msg, "close");
301 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
302#line 131 "sqlda.pgc"
303
304if (sqlca.sqlcode < 0) exit (1);}
305#line 131 "sqlda.pgc"
306
307
308 strcpy(msg, "deallocate");
309 { ECPGdeallocate(__LINE__, 0, NULL, "st_id1");
310#line 134 "sqlda.pgc"
311
312if (sqlca.sqlcode < 0) exit (1);}
313#line 134 "sqlda.pgc"
314
315
317
318 /* SQLDA test for getting ALL records into the sqlda list */
319
320 outp_sqlda = NULL;
321
322 strcpy(msg, "prepare");
323 { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt1);
324#line 143 "sqlda.pgc"
325
326if (sqlca.sqlcode < 0) exit (1);}
327#line 143 "sqlda.pgc"
328
329
330 strcpy(msg, "declare");
331 /* declare mycur2 cursor for $1 */
332#line 146 "sqlda.pgc"
333
334
335 strcpy(msg, "open");
336 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1",
337 ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
338 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
339#line 149 "sqlda.pgc"
340
341if (sqlca.sqlcode < 0) exit (1);}
342#line 149 "sqlda.pgc"
343
344
345 strcpy(msg, "fetch");
346 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT,
347 ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L,
348 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
349#line 152 "sqlda.pgc"
350
351if (sqlca.sqlcode < 0) exit (1);}
352#line 152 "sqlda.pgc"
353
354
356 rec = 0;
357 while (outp_sqlda1)
358 {
359 sqlda_t *ptr;
360 printf("FETCH RECORD %d\n", ++rec);
362
363 ptr = outp_sqlda1;
365 free(ptr);
366 }
367
368 strcpy(msg, "close");
369 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
370#line 168 "sqlda.pgc"
371
372if (sqlca.sqlcode < 0) exit (1);}
373#line 168 "sqlda.pgc"
374
375
376 strcpy(msg, "deallocate");
377 { ECPGdeallocate(__LINE__, 0, NULL, "st_id2");
378#line 171 "sqlda.pgc"
379
380if (sqlca.sqlcode < 0) exit (1);}
381#line 171 "sqlda.pgc"
382
383
384 /* SQLDA test for getting one record using an input descriptor */
385
386 /*
387 * Input sqlda has to be built manually
388 * sqlda_t contains 1 sqlvar_t structure already.
389 */
390 inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t));
391 memset(inp_sqlda, 0, sizeof(sqlda_t));
392 inp_sqlda->sqln = 1;
393
395 inp_sqlda->sqlvar[0].sqldata = (char *)&id;
396
397 printf("EXECUTE RECORD 4\n");
398
399 id = 4;
400
401 outp_sqlda = NULL;
402
403 strcpy(msg, "prepare");
404 { ECPGprepare(__LINE__, NULL, 0, "st_id3", stmt2);
405#line 193 "sqlda.pgc"
406
407if (sqlca.sqlcode < 0) exit (1);}
408#line 193 "sqlda.pgc"
409
410
411 strcpy(msg, "execute");
412 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "st_id3",
413 ECPGt_sqlda, &inp_sqlda, 0L, 0L, 0L,
414 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
415 ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L,
416 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
417#line 196 "sqlda.pgc"
418
419if (sqlca.sqlcode < 0) exit (1);}
420#line 196 "sqlda.pgc"
421
422
424
425 strcpy(msg, "deallocate");
426 { ECPGdeallocate(__LINE__, 0, NULL, "st_id3");
427#line 201 "sqlda.pgc"
428
429if (sqlca.sqlcode < 0) exit (1);}
430#line 201 "sqlda.pgc"
431
432
435
436 /* SQLDA test for getting one record using an input descriptor
437 * on a named connection
438 */
439
440 { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , "con2", 0);
441#line 210 "sqlda.pgc"
442
443if (sqlca.sqlcode < 0) exit (1);}
444#line 210 "sqlda.pgc"
445
446
447 /*
448 * Input sqlda has to be built manually
449 * sqlda_t contains 1 sqlvar_t structure already.
450 */
451 inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t));
452 memset(inp_sqlda, 0, sizeof(sqlda_t));
453 inp_sqlda->sqln = 1;
454
456 inp_sqlda->sqlvar[0].sqldata = (char *)&id;
457
458 printf("EXECUTE RECORD 4\n");
459
460 id = 4;
461
462 outp_sqlda = NULL;
463
464 strcpy(msg, "prepare");
465 { ECPGprepare(__LINE__, "con2", 0, "st_id4", stmt2);
466#line 230 "sqlda.pgc"
467
468if (sqlca.sqlcode < 0) exit (1);}
469#line 230 "sqlda.pgc"
470
471
472 strcpy(msg, "execute");
473 { ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_execute, "st_id4",
474 ECPGt_sqlda, &inp_sqlda, 0L, 0L, 0L,
475 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
476 ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L,
477 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
478#line 233 "sqlda.pgc"
479
480if (sqlca.sqlcode < 0) exit (1);}
481#line 233 "sqlda.pgc"
482
483
485
486 strcpy(msg, "commit");
487 { ECPGtrans(__LINE__, "con2", "commit");
488#line 238 "sqlda.pgc"
489
490if (sqlca.sqlcode < 0) exit (1);}
491#line 238 "sqlda.pgc"
492
493
494 strcpy(msg, "deallocate");
495 { ECPGdeallocate(__LINE__, 0, NULL, "st_id4");
496#line 241 "sqlda.pgc"
497
498if (sqlca.sqlcode < 0) exit (1);}
499#line 241 "sqlda.pgc"
500
501
504
505 strcpy(msg, "disconnect");
506 { ECPGdisconnect(__LINE__, "con2");
507#line 247 "sqlda.pgc"
508
509if (sqlca.sqlcode < 0) exit (1);}
510#line 247 "sqlda.pgc"
511
512
513 /* End test */
514
515 strcpy(msg, "drop");
516 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
517#line 252 "sqlda.pgc"
518
519if (sqlca.sqlcode < 0) exit (1);}
520#line 252 "sqlda.pgc"
521
522
523 strcpy(msg, "commit");
524 { ECPGtrans(__LINE__, NULL, "commit");
525#line 255 "sqlda.pgc"
526
527if (sqlca.sqlcode < 0) exit (1);}
528#line 255 "sqlda.pgc"
529
530
531 strcpy(msg, "disconnect");
532 { ECPGdisconnect(__LINE__, "CURRENT");
533#line 258 "sqlda.pgc"
534
535if (sqlca.sqlcode < 0) exit (1);}
536#line 258 "sqlda.pgc"
537
538
539 return 0;
540}
bool ECPGdisconnect(int lineno, const char *connection_name)
Definition: connect.c:676
bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
Definition: connect.c:255
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
@ ECPGst_normal
Definition: ecpgtype.h:97
@ ECPGst_execute
Definition: ecpgtype.h:98
@ ECPGt_EOIT
Definition: ecpgtype.h:62
@ ECPGt_sqlda
Definition: ecpgtype.h:66
@ ECPGt_char_variable
Definition: ecpgtype.h:60
@ ECPGt_NO_INDICATOR
Definition: ecpgtype.h:64
@ ECPGt_EORT
Definition: ecpgtype.h:63
bool ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
Definition: execute.c:2275
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
bool ECPGtrans(int lineno, const char *connection_name, const char *transaction)
Definition: misc.c:160
char * ECPGprepared_statement(const char *connection_name, const char *name, int lineno)
Definition: prepare.c:368
bool ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
Definition: prepare.c:217
bool ECPGdeallocate(int lineno, int c, const char *connection_name, const char *name)
Definition: prepare.c:315
exit(1)
sqlda_t * outp_sqlda1
Definition: sql-sqlda.c:128
static void dump_sqlda(sqlda_t *sqlda)
Definition: sql-sqlda.c:131
sqlda_t * inp_sqlda
Definition: sql-sqlda.c:128
#define ECPGdebug(X, Y)
Definition: sql-sqlda.c:7
sqlda_t * outp_sqlda
Definition: sql-sqlda.c:128
#define sqlca
Definition: sqlca.h:59
struct sqlda_struct * desc_next
Definition: sqlda-native.h:39

References sqlda_struct::desc_next, dump_sqlda(), ECPG_NOT_FOUND, ECPGconnect(), ECPGdeallocate(), ECPGdebug, ECPGdisconnect(), ECPGdo(), ECPGprepare(), ECPGprepared_statement(), ECPGst_execute, ECPGst_normal, ECPGt_char_variable, ECPGt_EOIT, ECPGt_EORT, ECPGt_int, ECPGt_NO_INDICATOR, ECPGt_sqlda, ECPGtrans(), exit(), free, inp_sqlda, malloc, outp_sqlda, outp_sqlda1, printf, sqlca, sqlvar_struct::sqldata, sqlda_struct::sqln, sqlvar_struct::sqltype, and sqlda_struct::sqlvar.

◆ PGTYPESdecimal_free()

void PGTYPESdecimal_free ( decimal var)

Definition at line 392 of file numeric.c.

393{
394 free(var);
395}

◆ PGTYPESdecimal_new()

decimal * PGTYPESdecimal_new ( void  )

Definition at line 59 of file numeric.c.

60{
61 decimal *var;
62
63 if ((var = (decimal *) pgtypes_alloc(sizeof(decimal))) == NULL)
64 return NULL;
65
66 memset(var, 0, sizeof(decimal));
67
68 return var;
69}
char * pgtypes_alloc(long size)
Definition: common.c:10

◆ PGTYPESnumeric_add()

int PGTYPESnumeric_add ( numeric var1,
numeric var2,
numeric result 
)

Definition at line 637 of file numeric.c.

638{
639 /*
640 * Decide on the signs of the two variables what to do
641 */
642 if (var1->sign == NUMERIC_POS)
643 {
644 if (var2->sign == NUMERIC_POS)
645 {
646 /*
647 * Both are positive result = +(ABS(var1) + ABS(var2))
648 */
649 if (add_abs(var1, var2, result) != 0)
650 return -1;
651 result->sign = NUMERIC_POS;
652 }
653 else
654 {
655 /*
656 * var1 is positive, var2 is negative Must compare absolute values
657 */
658 switch (cmp_abs(var1, var2))
659 {
660 case 0:
661 /* ----------
662 * ABS(var1) == ABS(var2)
663 * result = ZERO
664 * ----------
665 */
666 zero_var(result);
667 result->rscale = Max(var1->rscale, var2->rscale);
668 result->dscale = Max(var1->dscale, var2->dscale);
669 break;
670
671 case 1:
672 /* ----------
673 * ABS(var1) > ABS(var2)
674 * result = +(ABS(var1) - ABS(var2))
675 * ----------
676 */
677 if (sub_abs(var1, var2, result) != 0)
678 return -1;
679 result->sign = NUMERIC_POS;
680 break;
681
682 case -1:
683 /* ----------
684 * ABS(var1) < ABS(var2)
685 * result = -(ABS(var2) - ABS(var1))
686 * ----------
687 */
688 if (sub_abs(var2, var1, result) != 0)
689 return -1;
690 result->sign = NUMERIC_NEG;
691 break;
692 }
693 }
694 }
695 else
696 {
697 if (var2->sign == NUMERIC_POS)
698 {
699 /* ----------
700 * var1 is negative, var2 is positive
701 * Must compare absolute values
702 * ----------
703 */
704 switch (cmp_abs(var1, var2))
705 {
706 case 0:
707 /* ----------
708 * ABS(var1) == ABS(var2)
709 * result = ZERO
710 * ----------
711 */
712 zero_var(result);
713 result->rscale = Max(var1->rscale, var2->rscale);
714 result->dscale = Max(var1->dscale, var2->dscale);
715 break;
716
717 case 1:
718 /* ----------
719 * ABS(var1) > ABS(var2)
720 * result = -(ABS(var1) - ABS(var2))
721 * ----------
722 */
723 if (sub_abs(var1, var2, result) != 0)
724 return -1;
725 result->sign = NUMERIC_NEG;
726 break;
727
728 case -1:
729 /* ----------
730 * ABS(var1) < ABS(var2)
731 * result = +(ABS(var2) - ABS(var1))
732 * ----------
733 */
734 if (sub_abs(var2, var1, result) != 0)
735 return -1;
736 result->sign = NUMERIC_POS;
737 break;
738 }
739 }
740 else
741 {
742 /* ----------
743 * Both are negative
744 * result = -(ABS(var1) + ABS(var2))
745 * ----------
746 */
747 if (add_abs(var1, var2, result) != 0)
748 return -1;
749 result->sign = NUMERIC_NEG;
750 }
751 }
752
753 return 0;
754}
#define NUMERIC_NEG
Definition: numeric.c:169
#define NUMERIC_POS
Definition: numeric.c:168
#define Max(x, y)
Definition: numeric.c:13
static int sub_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:553
static int add_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:465
static void zero_var(numeric *var)
Definition: numeric.c:374
static int cmp_abs(numeric *var1, numeric *var2)
Definition: numeric.c:407

◆ PGTYPESnumeric_cmp()

int PGTYPESnumeric_cmp ( numeric var1,
numeric var2 
)

Definition at line 1281 of file numeric.c.

1282{
1283 /* use cmp_abs function to calculate the result */
1284
1285 /* both are positive: normal comparison with cmp_abs */
1286 if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_POS)
1287 return cmp_abs(var1, var2);
1288
1289 /* both are negative: return the inverse of the normal comparison */
1290 if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_NEG)
1291 {
1292 /*
1293 * instead of inverting the result, we invert the parameter ordering
1294 */
1295 return cmp_abs(var2, var1);
1296 }
1297
1298 /* one is positive, one is negative: trivial */
1299 if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_NEG)
1300 return 1;
1301 if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_POS)
1302 return -1;
1303
1305 return INT_MAX;
1306}
#define PGTYPES_NUM_BAD_NUMERIC
Definition: pgtypes_error.h:4

◆ PGTYPESnumeric_copy()

int PGTYPESnumeric_copy ( numeric src,
numeric dst 
)

Definition at line 1388 of file numeric.c.

1389{
1390 int i;
1391
1392 if (dst == NULL)
1393 return -1;
1394 zero_var(dst);
1395
1396 dst->weight = src->weight;
1397 dst->rscale = src->rscale;
1398 dst->dscale = src->dscale;
1399 dst->sign = src->sign;
1400
1401 if (alloc_var(dst, src->ndigits) != 0)
1402 return -1;
1403
1404 for (i = 0; i < src->ndigits; i++)
1405 dst->digits[i] = src->digits[i];
1406
1407 return 0;
1408}
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:29
NumericDigit * digits

Referenced by numericvar_to_double(), PGTYPESnumeric_from_double(), and PGTYPESnumeric_to_asc().

◆ PGTYPESnumeric_div()

int PGTYPESnumeric_div ( numeric var1,
numeric var2,
numeric result 
)

Definition at line 1053 of file numeric.c.

1054{
1055 NumericDigit *res_digits;
1056 int res_ndigits;
1057 int res_sign;
1058 int res_weight;
1059 numeric dividend;
1060 numeric divisor[10];
1061 int ndigits_tmp;
1062 int weight_tmp;
1063 int rscale_tmp;
1064 int ri;
1065 long guess;
1066 long first_have;
1067 long first_div;
1068 int first_nextdigit;
1069 int stat = 0;
1070 int rscale;
1071 int res_dscale = select_div_scale(var1, var2, &rscale);
1072 int err = -1;
1073 NumericDigit *tmp_buf;
1074
1075 /*
1076 * First of all division by zero check
1077 */
1078 ndigits_tmp = var2->ndigits + 1;
1079 if (ndigits_tmp == 1)
1080 {
1082 return -1;
1083 }
1084
1085 /*
1086 * Determine the result sign, weight and number of digits to calculate
1087 */
1088 if (var1->sign == var2->sign)
1089 res_sign = NUMERIC_POS;
1090 else
1091 res_sign = NUMERIC_NEG;
1092 res_weight = var1->weight - var2->weight + 1;
1093 res_ndigits = rscale + res_weight;
1094 if (res_ndigits <= 0)
1095 res_ndigits = 1;
1096
1097 /*
1098 * Now result zero check
1099 */
1100 if (var1->ndigits == 0)
1101 {
1102 zero_var(result);
1103 result->rscale = rscale;
1104 return 0;
1105 }
1106
1107 /*
1108 * Initialize local variables
1109 */
1110 init_var(&dividend);
1111 for (int i = 1; i < 10; i++)
1112 init_var(&divisor[i]);
1113
1114 /*
1115 * Make a copy of the divisor which has one leading zero digit
1116 */
1117 divisor[1].ndigits = ndigits_tmp;
1118 divisor[1].rscale = var2->ndigits;
1119 divisor[1].sign = NUMERIC_POS;
1120 divisor[1].buf = digitbuf_alloc(ndigits_tmp);
1121 if (divisor[1].buf == NULL)
1122 goto done;
1123 divisor[1].digits = divisor[1].buf;
1124 divisor[1].digits[0] = 0;
1125 memcpy(&(divisor[1].digits[1]), var2->digits, ndigits_tmp - 1);
1126
1127 /*
1128 * Make a copy of the dividend
1129 */
1130 dividend.ndigits = var1->ndigits;
1131 dividend.weight = 0;
1132 dividend.rscale = var1->ndigits;
1133 dividend.sign = NUMERIC_POS;
1134 dividend.buf = digitbuf_alloc(var1->ndigits);
1135 if (dividend.buf == NULL)
1136 goto done;
1137 dividend.digits = dividend.buf;
1138 memcpy(dividend.digits, var1->digits, var1->ndigits);
1139
1140 /*
1141 * Setup the result. Do the allocation in a temporary buffer first, so we
1142 * don't free result->buf unless we have successfully allocated a buffer
1143 * to replace it with.
1144 */
1145 tmp_buf = digitbuf_alloc(res_ndigits + 2);
1146 if (tmp_buf == NULL)
1147 goto done;
1148 digitbuf_free(result->buf);
1149 result->buf = tmp_buf;
1150 res_digits = result->buf;
1151 result->digits = res_digits;
1152 result->ndigits = res_ndigits;
1153 result->weight = res_weight;
1154 result->rscale = rscale;
1155 result->sign = res_sign;
1156 res_digits[0] = 0;
1157
1158 first_div = divisor[1].digits[1] * 10;
1159 if (ndigits_tmp > 2)
1160 first_div += divisor[1].digits[2];
1161
1162 first_have = 0;
1163 first_nextdigit = 0;
1164
1165 weight_tmp = 1;
1166 rscale_tmp = divisor[1].rscale;
1167
1168 for (ri = 0; ri <= res_ndigits; ri++)
1169 {
1170 first_have = first_have * 10;
1171 if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits)
1172 first_have += dividend.digits[first_nextdigit];
1173 first_nextdigit++;
1174
1175 guess = (first_have * 10) / first_div + 1;
1176 if (guess > 9)
1177 guess = 9;
1178
1179 while (guess > 0)
1180 {
1181 if (divisor[guess].buf == NULL)
1182 {
1183 int i;
1184 long sum = 0;
1185
1186 memcpy(&divisor[guess], &divisor[1], sizeof(numeric));
1187 divisor[guess].buf = digitbuf_alloc(divisor[guess].ndigits);
1188 if (divisor[guess].buf == NULL)
1189 goto done;
1190 divisor[guess].digits = divisor[guess].buf;
1191 for (i = divisor[1].ndigits - 1; i >= 0; i--)
1192 {
1193 sum += divisor[1].digits[i] * guess;
1194 divisor[guess].digits[i] = sum % 10;
1195 sum /= 10;
1196 }
1197 }
1198
1199 divisor[guess].weight = weight_tmp;
1200 divisor[guess].rscale = rscale_tmp;
1201
1202 stat = cmp_abs(&dividend, &divisor[guess]);
1203 if (stat >= 0)
1204 break;
1205
1206 guess--;
1207 }
1208
1209 res_digits[ri + 1] = guess;
1210 if (stat == 0)
1211 {
1212 ri++;
1213 break;
1214 }
1215
1216 weight_tmp--;
1217 rscale_tmp++;
1218
1219 if (guess == 0)
1220 continue;
1221
1222 if (sub_abs(&dividend, &divisor[guess], &dividend) != 0)
1223 goto done;
1224
1225 first_nextdigit = dividend.weight - weight_tmp;
1226 first_have = 0;
1227 if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits)
1228 first_have = dividend.digits[first_nextdigit];
1229 first_nextdigit++;
1230 }
1231
1232 result->ndigits = ri + 1;
1233 if (ri == res_ndigits + 1)
1234 {
1235 int carry = (res_digits[ri] > 4) ? 1 : 0;
1236
1237 result->ndigits = ri;
1238 res_digits[ri] = 0;
1239
1240 while (carry && ri > 0)
1241 {
1242 carry += res_digits[--ri];
1243 res_digits[ri] = carry % 10;
1244 carry /= 10;
1245 }
1246 }
1247
1248 while (result->ndigits > 0 && *(result->digits) == 0)
1249 {
1250 (result->digits)++;
1251 (result->weight)--;
1252 (result->ndigits)--;
1253 }
1254 while (result->ndigits > 0 && result->digits[result->ndigits - 1] == 0)
1255 (result->ndigits)--;
1256 if (result->ndigits == 0)
1257 result->sign = NUMERIC_POS;
1258
1259 result->dscale = res_dscale;
1260 err = 0; /* if we've made it this far, return success */
1261
1262done:
1263
1264 /*
1265 * Tidy up
1266 */
1267 if (dividend.buf != NULL)
1268 digitbuf_free(dividend.buf);
1269
1270 for (int i = 1; i < 10; i++)
1271 {
1272 if (divisor[i].buf != NULL)
1273 digitbuf_free(divisor[i].buf);
1274 }
1275
1276 return err;
1277}
int16 NumericDigit
Definition: numeric.c:102
void err(int eval, const char *fmt,...)
Definition: err.c:43
int digits
Definition: informix.c:691
#define digitbuf_free(buf)
Definition: numeric.c:19
#define digitbuf_alloc(size)
Definition: numeric.c:18
static int select_div_scale(numeric *var1, numeric *var2, int *rscale)
Definition: numeric.c:987
#define init_var(v)
Definition: numeric.c:16
static char * buf
Definition: pg_test_fsync.c:72
#define PGTYPES_NUM_DIVIDE_ZERO
Definition: pgtypes_error.h:5
NumericDigit * buf

◆ PGTYPESnumeric_free()

void PGTYPESnumeric_free ( numeric var)

Definition at line 385 of file numeric.c.

386{
387 digitbuf_free(var->buf);
388 free(var);
389}

Referenced by numericvar_to_double(), PGTYPESnumeric_from_asc(), PGTYPESnumeric_from_double(), and PGTYPESnumeric_to_asc().

◆ PGTYPESnumeric_from_asc()

numeric * PGTYPESnumeric_from_asc ( char *  str,
char **  endptr 
)

Definition at line 321 of file numeric.c.

322{
323 numeric *value = (numeric *) pgtypes_alloc(sizeof(numeric));
324 int ret;
325
326 char *realptr;
327 char **ptr = (endptr != NULL) ? endptr : &realptr;
328
329 if (!value)
330 return NULL;
331
332 ret = set_var_from_str(str, ptr, value);
333 if (ret)
334 {
336 return NULL;
337 }
338
339 return value;
340}
const char * str
static struct @162 value
static int set_var_from_str(char *str, char **ptr, numeric *dest)
Definition: numeric.c:78
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:385

Referenced by PGTYPESnumeric_from_double().

◆ PGTYPESnumeric_from_decimal()

int PGTYPESnumeric_from_decimal ( decimal src,
numeric dst 
)

Definition at line 1570 of file numeric.c.

1571{
1572 int i;
1573
1574 zero_var(dst);
1575
1576 dst->weight = src->weight;
1577 dst->rscale = src->rscale;
1578 dst->dscale = src->dscale;
1579 dst->sign = src->sign;
1580
1581 if (alloc_var(dst, src->ndigits) != 0)
1582 return -1;
1583
1584 for (i = 0; i < src->ndigits; i++)
1585 dst->digits[i] = src->digits[i];
1586
1587 return 0;
1588}
NumericDigit digits[DECSIZE]

◆ PGTYPESnumeric_from_double()

int PGTYPESnumeric_from_double ( double  d,
numeric dst 
)

Definition at line 1411 of file numeric.c.

1412{
1413 char buffer[DBL_DIG + 100];
1414 numeric *tmp;
1415 int i;
1416
1417 if (sprintf(buffer, "%.*g", DBL_DIG, d) <= 0)
1418 return -1;
1419
1420 if ((tmp = PGTYPESnumeric_from_asc(buffer, NULL)) == NULL)
1421 return -1;
1422 i = PGTYPESnumeric_copy(tmp, dst);
1424 if (i != 0)
1425 return -1;
1426
1427 errno = 0;
1428 return 0;
1429}
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
Definition: numeric.c:1388
numeric * PGTYPESnumeric_from_asc(char *str, char **endptr)
Definition: numeric.c:321
#define sprintf
Definition: port.h:241

◆ PGTYPESnumeric_from_int()

int PGTYPESnumeric_from_int ( signed int  int_val,
numeric var 
)

Definition at line 1309 of file numeric.c.

1310{
1311 /* implicit conversion */
1312 signed long int long_int = int_val;
1313
1314 return PGTYPESnumeric_from_long(long_int, var);
1315}
int PGTYPESnumeric_from_long(signed long int long_val, numeric *var)
Definition: numeric.c:1318

◆ PGTYPESnumeric_from_long()

int PGTYPESnumeric_from_long ( signed long int  long_val,
numeric var 
)

Definition at line 1318 of file numeric.c.

1319{
1320 /* calculate the size of the long int number */
1321 /* a number n needs log_10 n digits */
1322
1323 /*
1324 * however we multiply by 10 each time and compare instead of calculating
1325 * the logarithm
1326 */
1327
1328 int size = 0;
1329 int i;
1330 signed long int abs_long_val = long_val;
1331 signed long int extract;
1332 signed long int reach_limit;
1333
1334 if (abs_long_val < 0)
1335 {
1336 abs_long_val *= -1;
1337 var->sign = NUMERIC_NEG;
1338 }
1339 else
1340 var->sign = NUMERIC_POS;
1341
1342 reach_limit = 1;
1343 do
1344 {
1345 size++;
1346 reach_limit *= 10;
1347 } while (reach_limit - 1 < abs_long_val && reach_limit <= LONG_MAX / 10);
1348
1349 if (reach_limit > LONG_MAX / 10)
1350 {
1351 /* add the first digit and a .0 */
1352 size += 2;
1353 }
1354 else
1355 {
1356 /* always add a .0 */
1357 size++;
1358 reach_limit /= 10;
1359 }
1360
1361 if (alloc_var(var, size) < 0)
1362 return -1;
1363
1364 var->rscale = 1;
1365 var->dscale = 1;
1366 var->weight = size - 2;
1367
1368 i = 0;
1369 do
1370 {
1371 extract = abs_long_val - (abs_long_val % reach_limit);
1372 var->digits[i] = extract / reach_limit;
1373 abs_long_val -= extract;
1374 i++;
1375 reach_limit /= 10;
1376
1377 /*
1378 * we can abandon if abs_long_val reaches 0, because the memory is
1379 * initialized properly and filled with '0', so converting 10000 in
1380 * only one step is no problem
1381 */
1382 } while (abs_long_val > 0);
1383
1384 return 0;
1385}
static pg_noinline void Size size
Definition: slab.c:607

Referenced by PGTYPESnumeric_from_int().

◆ PGTYPESnumeric_mul()

int PGTYPESnumeric_mul ( numeric var1,
numeric var2,
numeric result 
)

Definition at line 896 of file numeric.c.

897{
898 NumericDigit *res_buf;
899 NumericDigit *res_digits;
900 int res_ndigits;
901 int res_weight;
902 int res_sign;
903 int i,
904 ri,
905 i1,
906 i2;
907 long sum = 0;
908 int global_rscale = var1->rscale + var2->rscale;
909
910 res_weight = var1->weight + var2->weight + 2;
911 res_ndigits = var1->ndigits + var2->ndigits + 1;
912 if (var1->sign == var2->sign)
913 res_sign = NUMERIC_POS;
914 else
915 res_sign = NUMERIC_NEG;
916
917 if ((res_buf = digitbuf_alloc(res_ndigits)) == NULL)
918 return -1;
919 res_digits = res_buf;
920 memset(res_digits, 0, res_ndigits);
921
922 ri = res_ndigits;
923 for (i1 = var1->ndigits - 1; i1 >= 0; i1--)
924 {
925 sum = 0;
926 i = --ri;
927
928 for (i2 = var2->ndigits - 1; i2 >= 0; i2--)
929 {
930 sum += res_digits[i] + var1->digits[i1] * var2->digits[i2];
931 res_digits[i--] = sum % 10;
932 sum /= 10;
933 }
934 res_digits[i] = sum;
935 }
936
937 i = res_weight + global_rscale + 2;
938 if (i >= 0 && i < res_ndigits)
939 {
940 sum = (res_digits[i] > 4) ? 1 : 0;
941 res_ndigits = i;
942 i--;
943 while (sum)
944 {
945 sum += res_digits[i];
946 res_digits[i--] = sum % 10;
947 sum /= 10;
948 }
949 }
950
951 while (res_ndigits > 0 && *res_digits == 0)
952 {
953 res_digits++;
954 res_weight--;
955 res_ndigits--;
956 }
957 while (res_ndigits > 0 && res_digits[res_ndigits - 1] == 0)
958 res_ndigits--;
959
960 if (res_ndigits == 0)
961 {
962 res_sign = NUMERIC_POS;
963 res_weight = 0;
964 }
965
966 digitbuf_free(result->buf);
967 result->buf = res_buf;
968 result->digits = res_digits;
969 result->ndigits = res_ndigits;
970 result->weight = res_weight;
971 result->rscale = global_rscale;
972 result->sign = res_sign;
973 result->dscale = var1->dscale + var2->dscale;
974
975 return 0;
976}

◆ PGTYPESnumeric_new()

numeric * PGTYPESnumeric_new ( void  )

Definition at line 42 of file numeric.c.

43{
44 numeric *var;
45
46 if ((var = (numeric *) pgtypes_alloc(sizeof(numeric))) == NULL)
47 return NULL;
48
49 if (alloc_var(var, 0) < 0)
50 {
51 free(var);
52 return NULL;
53 }
54
55 return var;
56}

Referenced by numericvar_to_double(), and PGTYPESnumeric_to_asc().

◆ PGTYPESnumeric_sub()

int PGTYPESnumeric_sub ( numeric var1,
numeric var2,
numeric result 
)

Definition at line 765 of file numeric.c.

766{
767 /*
768 * Decide on the signs of the two variables what to do
769 */
770 if (var1->sign == NUMERIC_POS)
771 {
772 if (var2->sign == NUMERIC_NEG)
773 {
774 /* ----------
775 * var1 is positive, var2 is negative
776 * result = +(ABS(var1) + ABS(var2))
777 * ----------
778 */
779 if (add_abs(var1, var2, result) != 0)
780 return -1;
781 result->sign = NUMERIC_POS;
782 }
783 else
784 {
785 /* ----------
786 * Both are positive
787 * Must compare absolute values
788 * ----------
789 */
790 switch (cmp_abs(var1, var2))
791 {
792 case 0:
793 /* ----------
794 * ABS(var1) == ABS(var2)
795 * result = ZERO
796 * ----------
797 */
798 zero_var(result);
799 result->rscale = Max(var1->rscale, var2->rscale);
800 result->dscale = Max(var1->dscale, var2->dscale);
801 break;
802
803 case 1:
804 /* ----------
805 * ABS(var1) > ABS(var2)
806 * result = +(ABS(var1) - ABS(var2))
807 * ----------
808 */
809 if (sub_abs(var1, var2, result) != 0)
810 return -1;
811 result->sign = NUMERIC_POS;
812 break;
813
814 case -1:
815 /* ----------
816 * ABS(var1) < ABS(var2)
817 * result = -(ABS(var2) - ABS(var1))
818 * ----------
819 */
820 if (sub_abs(var2, var1, result) != 0)
821 return -1;
822 result->sign = NUMERIC_NEG;
823 break;
824 }
825 }
826 }
827 else
828 {
829 if (var2->sign == NUMERIC_NEG)
830 {
831 /* ----------
832 * Both are negative
833 * Must compare absolute values
834 * ----------
835 */
836 switch (cmp_abs(var1, var2))
837 {
838 case 0:
839 /* ----------
840 * ABS(var1) == ABS(var2)
841 * result = ZERO
842 * ----------
843 */
844 zero_var(result);
845 result->rscale = Max(var1->rscale, var2->rscale);
846 result->dscale = Max(var1->dscale, var2->dscale);
847 break;
848
849 case 1:
850 /* ----------
851 * ABS(var1) > ABS(var2)
852 * result = -(ABS(var1) - ABS(var2))
853 * ----------
854 */
855 if (sub_abs(var1, var2, result) != 0)
856 return -1;
857 result->sign = NUMERIC_NEG;
858 break;
859
860 case -1:
861 /* ----------
862 * ABS(var1) < ABS(var2)
863 * result = +(ABS(var2) - ABS(var1))
864 * ----------
865 */
866 if (sub_abs(var2, var1, result) != 0)
867 return -1;
868 result->sign = NUMERIC_POS;
869 break;
870 }
871 }
872 else
873 {
874 /* ----------
875 * var1 is negative, var2 is positive
876 * result = -(ABS(var1) + ABS(var2))
877 * ----------
878 */
879 if (add_abs(var1, var2, result) != 0)
880 return -1;
881 result->sign = NUMERIC_NEG;
882 }
883 }
884
885 return 0;
886}

◆ PGTYPESnumeric_to_asc()

char * PGTYPESnumeric_to_asc ( numeric num,
int  dscale 
)

Definition at line 343 of file numeric.c.

344{
345 numeric *numcopy = PGTYPESnumeric_new();
346 char *s;
347
348 if (numcopy == NULL)
349 return NULL;
350
351 if (PGTYPESnumeric_copy(num, numcopy) < 0)
352 {
353 PGTYPESnumeric_free(numcopy);
354 return NULL;
355 }
356
357 if (dscale < 0)
358 dscale = num->dscale;
359
360 /* get_str_from_var may change its argument */
361 s = get_str_from_var(numcopy, dscale);
362 PGTYPESnumeric_free(numcopy);
363 return s;
364}
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:42
static char * get_str_from_var(numeric *var, int dscale)
Definition: numeric.c:226

Referenced by dump_sqlda(), and PGTYPESnumeric_to_long().

◆ PGTYPESnumeric_to_decimal()

int PGTYPESnumeric_to_decimal ( numeric src,
decimal dst 
)

Definition at line 1547 of file numeric.c.

1548{
1549 int i;
1550
1551 if (src->ndigits > DECSIZE)
1552 {
1553 errno = PGTYPES_NUM_OVERFLOW;
1554 return -1;
1555 }
1556
1557 dst->weight = src->weight;
1558 dst->rscale = src->rscale;
1559 dst->dscale = src->dscale;
1560 dst->sign = src->sign;
1561 dst->ndigits = src->ndigits;
1562
1563 for (i = 0; i < src->ndigits; i++)
1564 dst->digits[i] = src->digits[i];
1565
1566 return 0;
1567}
#define PGTYPES_NUM_OVERFLOW
Definition: pgtypes_error.h:3
#define DECSIZE

◆ PGTYPESnumeric_to_double()

int PGTYPESnumeric_to_double ( numeric nv,
double *  dp 
)

Definition at line 1483 of file numeric.c.

1484{
1485 double tmp;
1486
1487 if (numericvar_to_double(nv, &tmp) != 0)
1488 return -1;
1489 *dp = tmp;
1490 return 0;
1491}
static int numericvar_to_double(numeric *var, double *dp)
Definition: numeric.c:1432

◆ PGTYPESnumeric_to_int()

int PGTYPESnumeric_to_int ( numeric nv,
int *  ip 
)

Definition at line 1494 of file numeric.c.

1495{
1496 long l;
1497 int i;
1498
1499 if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
1500 return i;
1501
1502/* silence compilers that might complain about useless tests */
1503#if SIZEOF_LONG > SIZEOF_INT
1504
1505 if (l < INT_MIN || l > INT_MAX)
1506 {
1507 errno = PGTYPES_NUM_OVERFLOW;
1508 return -1;
1509 }
1510
1511#endif
1512
1513 *ip = (int) l;
1514 return 0;
1515}
int PGTYPESnumeric_to_long(numeric *nv, long *lp)
Definition: numeric.c:1518

◆ PGTYPESnumeric_to_long()

int PGTYPESnumeric_to_long ( numeric nv,
long *  lp 
)

Definition at line 1518 of file numeric.c.

1519{
1520 char *s = PGTYPESnumeric_to_asc(nv, 0);
1521 char *endptr;
1522
1523 if (s == NULL)
1524 return -1;
1525
1526 errno = 0;
1527 *lp = strtol(s, &endptr, 10);
1528 if (endptr == s)
1529 {
1530 /* this should not happen actually */
1531 free(s);
1532 return -1;
1533 }
1534 free(s);
1535 if (errno == ERANGE)
1536 {
1537 if (*lp == LONG_MIN)
1538 errno = PGTYPES_NUM_UNDERFLOW;
1539 else
1540 errno = PGTYPES_NUM_OVERFLOW;
1541 return -1;
1542 }
1543 return 0;
1544}
char * PGTYPESnumeric_to_asc(numeric *num, int dscale)
Definition: numeric.c:343
#define PGTYPES_NUM_UNDERFLOW
Definition: pgtypes_error.h:6

Referenced by PGTYPESnumeric_to_int().

Variable Documentation

◆ inp_sqlda

sqlda_t* inp_sqlda

Definition at line 128 of file sql-sqlda.c.

Referenced by main().

◆ outp_sqlda

sqlda_t * outp_sqlda

Definition at line 128 of file sql-sqlda.c.

Referenced by main().

◆ outp_sqlda1

sqlda_t * outp_sqlda1

Definition at line 128 of file sql-sqlda.c.

Referenced by main().