PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
sql-sqlda.c File Reference
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "sqlda-native.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 *)
 
void PGTYPESdecimal_free (decimal *)
 
numericPGTYPESnumeric_from_asc (char *, char **)
 
char * PGTYPESnumeric_to_asc (numeric *, int)
 
int PGTYPESnumeric_add (numeric *, numeric *, numeric *)
 
int PGTYPESnumeric_sub (numeric *, numeric *, numeric *)
 
int PGTYPESnumeric_mul (numeric *, numeric *, numeric *)
 
int PGTYPESnumeric_div (numeric *, numeric *, numeric *)
 
int PGTYPESnumeric_cmp (numeric *, numeric *)
 
int PGTYPESnumeric_from_int (signed int, numeric *)
 
int PGTYPESnumeric_from_long (signed long int, numeric *)
 
int PGTYPESnumeric_copy (numeric *, numeric *)
 
int PGTYPESnumeric_from_double (double, numeric *)
 
int PGTYPESnumeric_to_double (numeric *, double *)
 
int PGTYPESnumeric_to_int (numeric *, int *)
 
int PGTYPESnumeric_to_long (numeric *, long *)
 
int PGTYPESnumeric_to_decimal (numeric *, decimal *)
 
int PGTYPESnumeric_from_decimal (decimal *, numeric *)
 
static void dump_sqlda (sqlda_t *sqlda)
 
int main (void)
 

Variables

sqlda_tinp_sqlda
 
sqlda_toutp_sqlda
 
sqlda_toutp_sqlda1
 

Macro Definition Documentation

#define DECSIZE   30

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

#define ECPG_SQLDA_H

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

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

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

Referenced by main().

#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION

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

#define NUMERIC_MAX_PRECISION   1000

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

#define NUMERIC_MIN_DISPLAY_SCALE   0

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

#define NUMERIC_MIN_SIG_DIGITS   16

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

#define NUMERIC_NAN   0xC000

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

#define NUMERIC_NEG   0x4000

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

#define NUMERIC_NULL   0xF000

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

#define NUMERIC_POS   0x0000

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

#define PGTYPES_NUMERIC

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

Typedef Documentation

typedef unsigned char NumericDigit

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

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

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

Function Documentation

static void dump_sqlda ( sqlda_t sqlda)
static

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

References sqlname::data, ECPGt_char, ECPGt_double, ECPGt_int, ECPGt_numeric, free, i, NULL, PGTYPESnumeric_to_asc(), sqlda_struct::sqld, sqlvar_struct::sqldata, sqlvar_struct::sqlind, sqlvar_struct::sqlname, sqlvar_struct::sqltype, sqlda_struct::sqlvar, and val.

Referenced by main().

130 {
131  int i;
132 
133  if (sqlda == NULL)
134  {
135  printf("dump_sqlda called with NULL sqlda\n");
136  return;
137  }
138 
139  for (i = 0; i < sqlda->sqld; i++)
140  {
141  if (sqlda->sqlvar[i].sqlind && *(sqlda->sqlvar[i].sqlind) == -1)
142  printf("name sqlda descriptor: '%s' value NULL'\n", sqlda->sqlvar[i].sqlname.data);
143  else
144  switch (sqlda->sqlvar[i].sqltype)
145  {
146  case ECPGt_char:
147  printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname.data, sqlda->sqlvar[i].sqldata);
148  break;
149  case ECPGt_int:
150  printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname.data, *(int *)sqlda->sqlvar[i].sqldata);
151  break;
152  case ECPGt_double:
153  printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname.data, *(double *)sqlda->sqlvar[i].sqldata);
154  break;
155  case ECPGt_numeric:
156  {
157  char *val;
158 
159  val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1);
160  printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val);
161  free(val);
162  break;
163  }
164  }
165  }
166 }
struct sqlvar_struct sqlvar[1]
Definition: sqlda-native.h:40
char * sqldata
Definition: sqlda-native.h:28
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
char * PGTYPESnumeric_to_asc(numeric *, int)
Definition: numeric.c:428
char data[NAMEDATALEN]
Definition: sqlda-native.h:21
short * sqlind
Definition: sqlda-native.h:29
int i
struct sqlname sqlname
Definition: sqlda-native.h:30
long val
Definition: informix.c:689
int main ( void  )

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

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(), free, malloc, NULL, outp_sqlda, outp_sqlda1, sqlca, sqlvar_struct::sqldata, sqlda_struct::sqln, sqlvar_struct::sqltype, and sqlda_struct::sqlvar.

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

Definition at line 477 of file numeric.c.

References free.

478 {
479  free(var);
480 }
#define free(a)
Definition: header.h:65
decimal* PGTYPESdecimal_new ( void  )

Definition at line 144 of file numeric.c.

References NULL, and pgtypes_alloc().

145 {
146  decimal *var;
147 
148  if ((var = (decimal *) pgtypes_alloc(sizeof(decimal))) == NULL)
149  return NULL;
150 
151  memset(var, 0, sizeof(decimal));
152 
153  return var;
154 }
char * pgtypes_alloc(long size)
Definition: common.c:9
#define NULL
Definition: c.h:229
int PGTYPESnumeric_add ( numeric ,
numeric ,
numeric  
)

Definition at line 722 of file numeric.c.

References add_abs(), cmp_abs(), numeric::dscale, Max, NUMERIC_NEG, NUMERIC_POS, numeric::rscale, numeric::sign, sub_abs(), and zero_var().

723 {
724  /*
725  * Decide on the signs of the two variables what to do
726  */
727  if (var1->sign == NUMERIC_POS)
728  {
729  if (var2->sign == NUMERIC_POS)
730  {
731  /*
732  * Both are positive result = +(ABS(var1) + ABS(var2))
733  */
734  if (add_abs(var1, var2, result) != 0)
735  return -1;
736  result->sign = NUMERIC_POS;
737  }
738  else
739  {
740  /*
741  * var1 is positive, var2 is negative Must compare absolute values
742  */
743  switch (cmp_abs(var1, var2))
744  {
745  case 0:
746  /* ----------
747  * ABS(var1) == ABS(var2)
748  * result = ZERO
749  * ----------
750  */
751  zero_var(result);
752  result->rscale = Max(var1->rscale, var2->rscale);
753  result->dscale = Max(var1->dscale, var2->dscale);
754  break;
755 
756  case 1:
757  /* ----------
758  * ABS(var1) > ABS(var2)
759  * result = +(ABS(var1) - ABS(var2))
760  * ----------
761  */
762  if (sub_abs(var1, var2, result) != 0)
763  return -1;
764  result->sign = NUMERIC_POS;
765  break;
766 
767  case -1:
768  /* ----------
769  * ABS(var1) < ABS(var2)
770  * result = -(ABS(var2) - ABS(var1))
771  * ----------
772  */
773  if (sub_abs(var2, var1, result) != 0)
774  return -1;
775  result->sign = NUMERIC_NEG;
776  break;
777  }
778  }
779  }
780  else
781  {
782  if (var2->sign == NUMERIC_POS)
783  {
784  /* ----------
785  * var1 is negative, var2 is positive
786  * Must compare absolute values
787  * ----------
788  */
789  switch (cmp_abs(var1, var2))
790  {
791  case 0:
792  /* ----------
793  * ABS(var1) == ABS(var2)
794  * result = ZERO
795  * ----------
796  */
797  zero_var(result);
798  result->rscale = Max(var1->rscale, var2->rscale);
799  result->dscale = Max(var1->dscale, var2->dscale);
800  break;
801 
802  case 1:
803  /* ----------
804  * ABS(var1) > ABS(var2)
805  * result = -(ABS(var1) - ABS(var2))
806  * ----------
807  */
808  if (sub_abs(var1, var2, result) != 0)
809  return -1;
810  result->sign = NUMERIC_NEG;
811  break;
812 
813  case -1:
814  /* ----------
815  * ABS(var1) < ABS(var2)
816  * result = +(ABS(var2) - ABS(var1))
817  * ----------
818  */
819  if (sub_abs(var2, var1, result) != 0)
820  return -1;
821  result->sign = NUMERIC_POS;
822  break;
823  }
824  }
825  else
826  {
827  /* ----------
828  * Both are negative
829  * result = -(ABS(var1) + ABS(var2))
830  * ----------
831  */
832  if (add_abs(var1, var2, result) != 0)
833  return -1;
834  result->sign = NUMERIC_NEG;
835  }
836  }
837 
838  return 0;
839 }
static int add_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:550
#define NUMERIC_POS
Definition: numeric.c:164
static void zero_var(numeric *var)
Definition: numeric.c:459
return result
Definition: formatting.c:1633
#define NUMERIC_NEG
Definition: numeric.c:165
static int cmp_abs(numeric *var1, numeric *var2)
Definition: numeric.c:492
static int sub_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:638
#define Max(x, y)
Definition: numeric.c:11
int PGTYPESnumeric_cmp ( numeric ,
numeric  
)

Definition at line 1367 of file numeric.c.

References cmp_abs(), NUMERIC_NEG, NUMERIC_POS, PGTYPES_NUM_BAD_NUMERIC, and numeric::sign.

1368 {
1369  /* use cmp_abs function to calculate the result */
1370 
1371  /* both are positive: normal comparison with cmp_abs */
1372  if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_POS)
1373  return cmp_abs(var1, var2);
1374 
1375  /* both are negative: return the inverse of the normal comparison */
1376  if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_NEG)
1377  {
1378  /*
1379  * instead of inverting the result, we invert the parameter ordering
1380  */
1381  return cmp_abs(var2, var1);
1382  }
1383 
1384  /* one is positive, one is negative: trivial */
1385  if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_NEG)
1386  return 1;
1387  if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_POS)
1388  return -1;
1389 
1390  errno = PGTYPES_NUM_BAD_NUMERIC;
1391  return INT_MAX;
1392 
1393 }
#define NUMERIC_POS
Definition: numeric.c:164
#define NUMERIC_NEG
Definition: numeric.c:165
static int cmp_abs(numeric *var1, numeric *var2)
Definition: numeric.c:492
#define PGTYPES_NUM_BAD_NUMERIC
Definition: pgtypes_error.h:4
int PGTYPESnumeric_copy ( numeric ,
numeric  
)

Definition at line 1475 of file numeric.c.

References alloc_var(), numeric::digits, numeric::dscale, i, numeric::ndigits, NULL, numeric::rscale, numeric::sign, numeric::weight, and zero_var().

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

1476 {
1477  int i;
1478 
1479  if (dst == NULL)
1480  return -1;
1481  zero_var(dst);
1482 
1483  dst->weight = src->weight;
1484  dst->rscale = src->rscale;
1485  dst->dscale = src->dscale;
1486  dst->sign = src->sign;
1487 
1488  if (alloc_var(dst, src->ndigits) != 0)
1489  return -1;
1490 
1491  for (i = 0; i < src->ndigits; i++)
1492  dst->digits[i] = src->digits[i];
1493 
1494  return 0;
1495 }
static void zero_var(numeric *var)
Definition: numeric.c:459
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:114
#define NULL
Definition: c.h:229
int i
int PGTYPESnumeric_div ( numeric ,
numeric ,
numeric  
)

Definition at line 1138 of file numeric.c.

References numeric::buf, buf, cmp_abs(), digitbuf_alloc, digitbuf_free, numeric::digits, digits, numeric::dscale, i, init_var, numeric::ndigits, NULL, NUMERIC_NEG, NUMERIC_POS, PGTYPES_NUM_DIVIDE_ZERO, numeric::rscale, select_div_scale(), numeric::sign, sub_abs(), numeric::weight, and zero_var().

1139 {
1140  NumericDigit *res_digits;
1141  int res_ndigits;
1142  int res_sign;
1143  int res_weight;
1144  numeric dividend;
1145  numeric divisor[10];
1146  int ndigits_tmp;
1147  int weight_tmp;
1148  int rscale_tmp;
1149  int ri;
1150  int i;
1151  long guess;
1152  long first_have;
1153  long first_div;
1154  int first_nextdigit;
1155  int stat = 0;
1156  int rscale;
1157  int res_dscale = select_div_scale(var1, var2, &rscale);
1158  int err = -1;
1159  NumericDigit *tmp_buf;
1160 
1161  /*
1162  * First of all division by zero check
1163  */
1164  ndigits_tmp = var2->ndigits + 1;
1165  if (ndigits_tmp == 1)
1166  {
1167  errno = PGTYPES_NUM_DIVIDE_ZERO;
1168  return -1;
1169  }
1170 
1171  /*
1172  * Determine the result sign, weight and number of digits to calculate
1173  */
1174  if (var1->sign == var2->sign)
1175  res_sign = NUMERIC_POS;
1176  else
1177  res_sign = NUMERIC_NEG;
1178  res_weight = var1->weight - var2->weight + 1;
1179  res_ndigits = rscale + res_weight;
1180  if (res_ndigits <= 0)
1181  res_ndigits = 1;
1182 
1183  /*
1184  * Now result zero check
1185  */
1186  if (var1->ndigits == 0)
1187  {
1188  zero_var(result);
1189  result->rscale = rscale;
1190  return 0;
1191  }
1192 
1193  /*
1194  * Initialize local variables
1195  */
1196  init_var(&dividend);
1197  for (i = 1; i < 10; i++)
1198  init_var(&divisor[i]);
1199 
1200  /*
1201  * Make a copy of the divisor which has one leading zero digit
1202  */
1203  divisor[1].ndigits = ndigits_tmp;
1204  divisor[1].rscale = var2->ndigits;
1205  divisor[1].sign = NUMERIC_POS;
1206  divisor[1].buf = digitbuf_alloc(ndigits_tmp);
1207  if (divisor[1].buf == NULL)
1208  goto done;
1209  divisor[1].digits = divisor[1].buf;
1210  divisor[1].digits[0] = 0;
1211  memcpy(&(divisor[1].digits[1]), var2->digits, ndigits_tmp - 1);
1212 
1213  /*
1214  * Make a copy of the dividend
1215  */
1216  dividend.ndigits = var1->ndigits;
1217  dividend.weight = 0;
1218  dividend.rscale = var1->ndigits;
1219  dividend.sign = NUMERIC_POS;
1220  dividend.buf = digitbuf_alloc(var1->ndigits);
1221  if (dividend.buf == NULL)
1222  goto done;
1223  dividend.digits = dividend.buf;
1224  memcpy(dividend.digits, var1->digits, var1->ndigits);
1225 
1226  /*
1227  * Setup the result. Do the allocation in a temporary buffer first, so we
1228  * don't free result->buf unless we have successfully allocated a buffer
1229  * to replace it with.
1230  */
1231  tmp_buf = digitbuf_alloc(res_ndigits + 2);
1232  if (tmp_buf == NULL)
1233  goto done;
1234  digitbuf_free(result->buf);
1235  result->buf = tmp_buf;
1236  res_digits = result->buf;
1237  result->digits = res_digits;
1238  result->ndigits = res_ndigits;
1239  result->weight = res_weight;
1240  result->rscale = rscale;
1241  result->sign = res_sign;
1242  res_digits[0] = 0;
1243 
1244  first_div = divisor[1].digits[1] * 10;
1245  if (ndigits_tmp > 2)
1246  first_div += divisor[1].digits[2];
1247 
1248  first_have = 0;
1249  first_nextdigit = 0;
1250 
1251  weight_tmp = 1;
1252  rscale_tmp = divisor[1].rscale;
1253 
1254  for (ri = 0; ri <= res_ndigits; ri++)
1255  {
1256  first_have = first_have * 10;
1257  if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits)
1258  first_have += dividend.digits[first_nextdigit];
1259  first_nextdigit++;
1260 
1261  guess = (first_have * 10) / first_div + 1;
1262  if (guess > 9)
1263  guess = 9;
1264 
1265  while (guess > 0)
1266  {
1267  if (divisor[guess].buf == NULL)
1268  {
1269  int i;
1270  long sum = 0;
1271 
1272  memcpy(&divisor[guess], &divisor[1], sizeof(numeric));
1273  divisor[guess].buf = digitbuf_alloc(divisor[guess].ndigits);
1274  if (divisor[guess].buf == NULL)
1275  goto done;
1276  divisor[guess].digits = divisor[guess].buf;
1277  for (i = divisor[1].ndigits - 1; i >= 0; i--)
1278  {
1279  sum += divisor[1].digits[i] * guess;
1280  divisor[guess].digits[i] = sum % 10;
1281  sum /= 10;
1282  }
1283  }
1284 
1285  divisor[guess].weight = weight_tmp;
1286  divisor[guess].rscale = rscale_tmp;
1287 
1288  stat = cmp_abs(&dividend, &divisor[guess]);
1289  if (stat >= 0)
1290  break;
1291 
1292  guess--;
1293  }
1294 
1295  res_digits[ri + 1] = guess;
1296  if (stat == 0)
1297  {
1298  ri++;
1299  break;
1300  }
1301 
1302  weight_tmp--;
1303  rscale_tmp++;
1304 
1305  if (guess == 0)
1306  continue;
1307 
1308  if (sub_abs(&dividend, &divisor[guess], &dividend) != 0)
1309  goto done;
1310 
1311  first_nextdigit = dividend.weight - weight_tmp;
1312  first_have = 0;
1313  if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits)
1314  first_have = dividend.digits[first_nextdigit];
1315  first_nextdigit++;
1316  }
1317 
1318  result->ndigits = ri + 1;
1319  if (ri == res_ndigits + 1)
1320  {
1321  int carry = (res_digits[ri] > 4) ? 1 : 0;
1322 
1323  result->ndigits = ri;
1324  res_digits[ri] = 0;
1325 
1326  while (carry && ri > 0)
1327  {
1328  carry += res_digits[--ri];
1329  res_digits[ri] = carry % 10;
1330  carry /= 10;
1331  }
1332  }
1333 
1334  while (result->ndigits > 0 && *(result->digits) == 0)
1335  {
1336  (result->digits)++;
1337  (result->weight)--;
1338  (result->ndigits)--;
1339  }
1340  while (result->ndigits > 0 && result->digits[result->ndigits - 1] == 0)
1341  (result->ndigits)--;
1342  if (result->ndigits == 0)
1343  result->sign = NUMERIC_POS;
1344 
1345  result->dscale = res_dscale;
1346  err = 0; /* if we've made it this far, return success */
1347 
1348 done:
1349 
1350  /*
1351  * Tidy up
1352  */
1353  if (dividend.buf != NULL)
1354  digitbuf_free(dividend.buf);
1355 
1356  for (i = 1; i < 10; i++)
1357  {
1358  if (divisor[i].buf != NULL)
1359  digitbuf_free(divisor[i].buf);
1360  }
1361 
1362  return err;
1363 }
#define PGTYPES_NUM_DIVIDE_ZERO
Definition: pgtypes_error.h:5
#define NUMERIC_POS
Definition: numeric.c:164
static void zero_var(numeric *var)
Definition: numeric.c:459
NumericDigit * buf
return result
Definition: formatting.c:1633
#define NUMERIC_NEG
Definition: numeric.c:165
#define digitbuf_alloc(size)
Definition: numeric.c:16
NumericDigit * digits
static char * buf
Definition: pg_test_fsync.c:66
int16 NumericDigit
Definition: numeric.c:99
static int cmp_abs(numeric *var1, numeric *var2)
Definition: numeric.c:492
static int select_div_scale(numeric *var1, numeric *var2, int *rscale)
Definition: numeric.c:1072
static int sub_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:638
#define NULL
Definition: c.h:229
#define digitbuf_free(buf)
Definition: numeric.c:17
#define init_var(v)
Definition: numeric.c:14
int i
int digits
Definition: informix.c:691
void PGTYPESnumeric_free ( numeric )

Definition at line 470 of file numeric.c.

References numeric::buf, digitbuf_free, and free.

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

471 {
472  digitbuf_free(var->buf);
473  free(var);
474 }
#define free(a)
Definition: header.h:65
#define digitbuf_free(buf)
Definition: numeric.c:17
numeric* PGTYPESnumeric_from_asc ( char *  ,
char **   
)

Definition at line 406 of file numeric.c.

References NULL, pgtypes_alloc(), PGTYPESnumeric_free(), set_var_from_str(), and value.

Referenced by PGTYPESnumeric_from_double().

407 {
408  numeric *value = (numeric *) pgtypes_alloc(sizeof(numeric));
409  int ret;
410 
411  char *realptr;
412  char **ptr = (endptr != NULL) ? endptr : &realptr;
413 
414  if (!value)
415  return (NULL);
416 
417  ret = set_var_from_str(str, ptr, value);
418  if (ret)
419  {
420  PGTYPESnumeric_free(value);
421  return (NULL);
422  }
423 
424  return (value);
425 }
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:470
static struct @121 value
char * pgtypes_alloc(long size)
Definition: common.c:9
static int set_var_from_str(char *str, char **ptr, numeric *dest)
Definition: numeric.c:163
#define NULL
Definition: c.h:229
int PGTYPESnumeric_from_decimal ( decimal ,
numeric  
)

Definition at line 1652 of file numeric.c.

References alloc_var(), numeric::digits, decimal::digits, numeric::dscale, decimal::dscale, i, decimal::ndigits, numeric::rscale, decimal::rscale, numeric::sign, decimal::sign, numeric::weight, decimal::weight, and zero_var().

1653 {
1654  int i;
1655 
1656  zero_var(dst);
1657 
1658  dst->weight = src->weight;
1659  dst->rscale = src->rscale;
1660  dst->dscale = src->dscale;
1661  dst->sign = src->sign;
1662 
1663  if (alloc_var(dst, src->ndigits) != 0)
1664  return -1;
1665 
1666  for (i = 0; i < src->ndigits; i++)
1667  dst->digits[i] = src->digits[i];
1668 
1669  return 0;
1670 }
static void zero_var(numeric *var)
Definition: numeric.c:459
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:114
int i
int PGTYPESnumeric_from_double ( double  ,
numeric  
)

Definition at line 1498 of file numeric.c.

References buffer, i, NULL, PGTYPESnumeric_copy(), PGTYPESnumeric_free(), and PGTYPESnumeric_from_asc().

1499 {
1500  char buffer[DBL_DIG + 100];
1501  numeric *tmp;
1502  int i;
1503 
1504  if (sprintf(buffer, "%.*g", DBL_DIG, d) <= 0)
1505  return -1;
1506 
1507  if ((tmp = PGTYPESnumeric_from_asc(buffer, NULL)) == NULL)
1508  return -1;
1509  i = PGTYPESnumeric_copy(tmp, dst);
1510  PGTYPESnumeric_free(tmp);
1511  if (i != 0)
1512  return -1;
1513 
1514  errno = 0;
1515  return 0;
1516 }
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:470
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
Definition: numeric.c:1475
#define NULL
Definition: c.h:229
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
numeric * PGTYPESnumeric_from_asc(char *str, char **endptr)
Definition: numeric.c:406
int i
int PGTYPESnumeric_from_int ( signed  int,
numeric  
)

Definition at line 1396 of file numeric.c.

References PGTYPESnumeric_from_long().

1397 {
1398  /* implicit conversion */
1399  signed long int long_int = int_val;
1400 
1401  return PGTYPESnumeric_from_long(long_int, var);
1402 }
int PGTYPESnumeric_from_long(signed long int long_val, numeric *var)
Definition: numeric.c:1405
int PGTYPESnumeric_from_long ( signed long  int,
numeric  
)

Definition at line 1405 of file numeric.c.

References alloc_var(), numeric::digits, numeric::dscale, i, NUMERIC_NEG, NUMERIC_POS, numeric::rscale, numeric::sign, and numeric::weight.

Referenced by PGTYPESnumeric_from_int().

1406 {
1407  /* calculate the size of the long int number */
1408  /* a number n needs log_10 n digits */
1409 
1410  /*
1411  * however we multiply by 10 each time and compare instead of calculating
1412  * the logarithm
1413  */
1414 
1415  int size = 0;
1416  int i;
1417  signed long int abs_long_val = long_val;
1418  signed long int extract;
1419  signed long int reach_limit;
1420 
1421  if (abs_long_val < 0)
1422  {
1423  abs_long_val *= -1;
1424  var->sign = NUMERIC_NEG;
1425  }
1426  else
1427  var->sign = NUMERIC_POS;
1428 
1429  reach_limit = 1;
1430  do
1431  {
1432  size++;
1433  reach_limit *= 10;
1434  } while (reach_limit - 1 < abs_long_val && reach_limit <= LONG_MAX / 10);
1435 
1436  if (reach_limit > LONG_MAX / 10)
1437  {
1438  /* add the first digit and a .0 */
1439  size += 2;
1440  }
1441  else
1442  {
1443  /* always add a .0 */
1444  size++;
1445  reach_limit /= 10;
1446  }
1447 
1448  if (alloc_var(var, size) < 0)
1449  return -1;
1450 
1451  var->rscale = 1;
1452  var->dscale = 1;
1453  var->weight = size - 2;
1454 
1455  i = 0;
1456  do
1457  {
1458  extract = abs_long_val - (abs_long_val % reach_limit);
1459  var->digits[i] = extract / reach_limit;
1460  abs_long_val -= extract;
1461  i++;
1462  reach_limit /= 10;
1463 
1464  /*
1465  * we can abandon if abs_long_val reaches 0, because the memory is
1466  * initialized properly and filled with '0', so converting 10000 in
1467  * only one step is no problem
1468  */
1469  } while (abs_long_val > 0);
1470 
1471  return 0;
1472 }
#define NUMERIC_POS
Definition: numeric.c:164
#define NUMERIC_NEG
Definition: numeric.c:165
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:114
int i
int PGTYPESnumeric_mul ( numeric ,
numeric ,
numeric  
)

Definition at line 981 of file numeric.c.

References numeric::buf, digitbuf_alloc, digitbuf_free, numeric::digits, numeric::dscale, i, numeric::ndigits, NULL, NUMERIC_NEG, NUMERIC_POS, numeric::rscale, numeric::sign, and numeric::weight.

982 {
983  NumericDigit *res_buf;
984  NumericDigit *res_digits;
985  int res_ndigits;
986  int res_weight;
987  int res_sign;
988  int i,
989  ri,
990  i1,
991  i2;
992  long sum = 0;
993  int global_rscale = var1->rscale + var2->rscale;
994 
995  res_weight = var1->weight + var2->weight + 2;
996  res_ndigits = var1->ndigits + var2->ndigits + 1;
997  if (var1->sign == var2->sign)
998  res_sign = NUMERIC_POS;
999  else
1000  res_sign = NUMERIC_NEG;
1001 
1002  if ((res_buf = digitbuf_alloc(res_ndigits)) == NULL)
1003  return -1;
1004  res_digits = res_buf;
1005  memset(res_digits, 0, res_ndigits);
1006 
1007  ri = res_ndigits;
1008  for (i1 = var1->ndigits - 1; i1 >= 0; i1--)
1009  {
1010  sum = 0;
1011  i = --ri;
1012 
1013  for (i2 = var2->ndigits - 1; i2 >= 0; i2--)
1014  {
1015  sum += res_digits[i] + var1->digits[i1] * var2->digits[i2];
1016  res_digits[i--] = sum % 10;
1017  sum /= 10;
1018  }
1019  res_digits[i] = sum;
1020  }
1021 
1022  i = res_weight + global_rscale + 2;
1023  if (i >= 0 && i < res_ndigits)
1024  {
1025  sum = (res_digits[i] > 4) ? 1 : 0;
1026  res_ndigits = i;
1027  i--;
1028  while (sum)
1029  {
1030  sum += res_digits[i];
1031  res_digits[i--] = sum % 10;
1032  sum /= 10;
1033  }
1034  }
1035 
1036  while (res_ndigits > 0 && *res_digits == 0)
1037  {
1038  res_digits++;
1039  res_weight--;
1040  res_ndigits--;
1041  }
1042  while (res_ndigits > 0 && res_digits[res_ndigits - 1] == 0)
1043  res_ndigits--;
1044 
1045  if (res_ndigits == 0)
1046  {
1047  res_sign = NUMERIC_POS;
1048  res_weight = 0;
1049  }
1050 
1051  digitbuf_free(result->buf);
1052  result->buf = res_buf;
1053  result->digits = res_digits;
1054  result->ndigits = res_ndigits;
1055  result->weight = res_weight;
1056  result->rscale = global_rscale;
1057  result->sign = res_sign;
1058  result->dscale = var1->dscale + var2->dscale;
1059 
1060  return 0;
1061 }
#define NUMERIC_POS
Definition: numeric.c:164
return result
Definition: formatting.c:1633
#define NUMERIC_NEG
Definition: numeric.c:165
#define digitbuf_alloc(size)
Definition: numeric.c:16
int16 NumericDigit
Definition: numeric.c:99
#define NULL
Definition: c.h:229
#define digitbuf_free(buf)
Definition: numeric.c:17
int i
numeric* PGTYPESnumeric_new ( void  )

Definition at line 127 of file numeric.c.

References alloc_var(), free, NULL, and pgtypes_alloc().

Referenced by numericvar_to_double(), and PGTYPESnumeric_to_asc().

128 {
129  numeric *var;
130 
131  if ((var = (numeric *) pgtypes_alloc(sizeof(numeric))) == NULL)
132  return NULL;
133 
134  if (alloc_var(var, 0) < 0)
135  {
136  free(var);
137  return NULL;
138  }
139 
140  return var;
141 }
char * pgtypes_alloc(long size)
Definition: common.c:9
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:114
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
int PGTYPESnumeric_sub ( numeric ,
numeric ,
numeric  
)

Definition at line 850 of file numeric.c.

References add_abs(), cmp_abs(), numeric::dscale, Max, NUMERIC_NEG, NUMERIC_POS, numeric::rscale, numeric::sign, sub_abs(), and zero_var().

851 {
852  /*
853  * Decide on the signs of the two variables what to do
854  */
855  if (var1->sign == NUMERIC_POS)
856  {
857  if (var2->sign == NUMERIC_NEG)
858  {
859  /* ----------
860  * var1 is positive, var2 is negative
861  * result = +(ABS(var1) + ABS(var2))
862  * ----------
863  */
864  if (add_abs(var1, var2, result) != 0)
865  return -1;
866  result->sign = NUMERIC_POS;
867  }
868  else
869  {
870  /* ----------
871  * Both are positive
872  * Must compare absolute values
873  * ----------
874  */
875  switch (cmp_abs(var1, var2))
876  {
877  case 0:
878  /* ----------
879  * ABS(var1) == ABS(var2)
880  * result = ZERO
881  * ----------
882  */
883  zero_var(result);
884  result->rscale = Max(var1->rscale, var2->rscale);
885  result->dscale = Max(var1->dscale, var2->dscale);
886  break;
887 
888  case 1:
889  /* ----------
890  * ABS(var1) > ABS(var2)
891  * result = +(ABS(var1) - ABS(var2))
892  * ----------
893  */
894  if (sub_abs(var1, var2, result) != 0)
895  return -1;
896  result->sign = NUMERIC_POS;
897  break;
898 
899  case -1:
900  /* ----------
901  * ABS(var1) < ABS(var2)
902  * result = -(ABS(var2) - ABS(var1))
903  * ----------
904  */
905  if (sub_abs(var2, var1, result) != 0)
906  return -1;
907  result->sign = NUMERIC_NEG;
908  break;
909  }
910  }
911  }
912  else
913  {
914  if (var2->sign == NUMERIC_NEG)
915  {
916  /* ----------
917  * Both are negative
918  * Must compare absolute values
919  * ----------
920  */
921  switch (cmp_abs(var1, var2))
922  {
923  case 0:
924  /* ----------
925  * ABS(var1) == ABS(var2)
926  * result = ZERO
927  * ----------
928  */
929  zero_var(result);
930  result->rscale = Max(var1->rscale, var2->rscale);
931  result->dscale = Max(var1->dscale, var2->dscale);
932  break;
933 
934  case 1:
935  /* ----------
936  * ABS(var1) > ABS(var2)
937  * result = -(ABS(var1) - ABS(var2))
938  * ----------
939  */
940  if (sub_abs(var1, var2, result) != 0)
941  return -1;
942  result->sign = NUMERIC_NEG;
943  break;
944 
945  case -1:
946  /* ----------
947  * ABS(var1) < ABS(var2)
948  * result = +(ABS(var2) - ABS(var1))
949  * ----------
950  */
951  if (sub_abs(var2, var1, result) != 0)
952  return -1;
953  result->sign = NUMERIC_POS;
954  break;
955  }
956  }
957  else
958  {
959  /* ----------
960  * var1 is negative, var2 is positive
961  * result = -(ABS(var1) + ABS(var2))
962  * ----------
963  */
964  if (add_abs(var1, var2, result) != 0)
965  return -1;
966  result->sign = NUMERIC_NEG;
967  }
968  }
969 
970  return 0;
971 }
static int add_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:550
#define NUMERIC_POS
Definition: numeric.c:164
static void zero_var(numeric *var)
Definition: numeric.c:459
return result
Definition: formatting.c:1633
#define NUMERIC_NEG
Definition: numeric.c:165
static int cmp_abs(numeric *var1, numeric *var2)
Definition: numeric.c:492
static int sub_abs(numeric *var1, numeric *var2, numeric *result)
Definition: numeric.c:638
#define Max(x, y)
Definition: numeric.c:11
char* PGTYPESnumeric_to_asc ( numeric ,
int   
)

Definition at line 428 of file numeric.c.

References numeric::dscale, get_str_from_var(), NULL, PGTYPESnumeric_copy(), PGTYPESnumeric_free(), and PGTYPESnumeric_new().

Referenced by dump_sqlda(), and PGTYPESnumeric_to_long().

429 {
430  numeric *numcopy = PGTYPESnumeric_new();
431  char *s;
432 
433  if (numcopy == NULL)
434  return NULL;
435 
436  if (PGTYPESnumeric_copy(num, numcopy) < 0)
437  {
438  PGTYPESnumeric_free(numcopy);
439  return NULL;
440  }
441 
442  if (dscale < 0)
443  dscale = num->dscale;
444 
445  /* get_str_from_var may change its argument */
446  s = get_str_from_var(numcopy, dscale);
447  PGTYPESnumeric_free(numcopy);
448  return (s);
449 }
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:127
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:470
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
Definition: numeric.c:1475
static char * get_str_from_var(numeric *var, int dscale)
Definition: numeric.c:311
#define NULL
Definition: c.h:229
int PGTYPESnumeric_to_decimal ( numeric ,
decimal  
)

Definition at line 1629 of file numeric.c.

References DECSIZE, numeric::digits, decimal::digits, numeric::dscale, decimal::dscale, i, numeric::ndigits, decimal::ndigits, PGTYPES_NUM_OVERFLOW, numeric::rscale, decimal::rscale, numeric::sign, decimal::sign, numeric::weight, and decimal::weight.

1630 {
1631  int i;
1632 
1633  if (src->ndigits > DECSIZE)
1634  {
1635  errno = PGTYPES_NUM_OVERFLOW;
1636  return -1;
1637  }
1638 
1639  dst->weight = src->weight;
1640  dst->rscale = src->rscale;
1641  dst->dscale = src->dscale;
1642  dst->sign = src->sign;
1643  dst->ndigits = src->ndigits;
1644 
1645  for (i = 0; i < src->ndigits; i++)
1646  dst->digits[i] = src->digits[i];
1647 
1648  return 0;
1649 }
#define PGTYPES_NUM_OVERFLOW
Definition: pgtypes_error.h:3
#define DECSIZE
int i
int PGTYPESnumeric_to_double ( numeric ,
double *   
)

Definition at line 1570 of file numeric.c.

References numericvar_to_double().

1571 {
1572  double tmp;
1573 
1574  if (numericvar_to_double(nv, &tmp) != 0)
1575  return -1;
1576  *dp = tmp;
1577  return 0;
1578 }
static int numericvar_to_double(numeric *var, double *dp)
Definition: numeric.c:1519
int PGTYPESnumeric_to_int ( numeric ,
int *   
)

Definition at line 1581 of file numeric.c.

References i, PGTYPES_NUM_OVERFLOW, and PGTYPESnumeric_to_long().

1582 {
1583  long l;
1584  int i;
1585 
1586  if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
1587  return i;
1588 
1589  if (l < -INT_MAX || l > INT_MAX)
1590  {
1591  errno = PGTYPES_NUM_OVERFLOW;
1592  return -1;
1593  }
1594 
1595  *ip = (int) l;
1596  return 0;
1597 }
#define PGTYPES_NUM_OVERFLOW
Definition: pgtypes_error.h:3
int i
int PGTYPESnumeric_to_long(numeric *nv, long *lp)
Definition: numeric.c:1600
int PGTYPESnumeric_to_long ( numeric ,
long *   
)

Definition at line 1600 of file numeric.c.

References free, NULL, PGTYPES_NUM_OVERFLOW, PGTYPES_NUM_UNDERFLOW, and PGTYPESnumeric_to_asc().

Referenced by PGTYPESnumeric_to_int().

1601 {
1602  char *s = PGTYPESnumeric_to_asc(nv, 0);
1603  char *endptr;
1604 
1605  if (s == NULL)
1606  return -1;
1607 
1608  errno = 0;
1609  *lp = strtol(s, &endptr, 10);
1610  if (endptr == s)
1611  {
1612  /* this should not happen actually */
1613  free(s);
1614  return -1;
1615  }
1616  free(s);
1617  if (errno == ERANGE)
1618  {
1619  if (*lp == LONG_MIN)
1620  errno = PGTYPES_NUM_UNDERFLOW;
1621  else
1622  errno = PGTYPES_NUM_OVERFLOW;
1623  return -1;
1624  }
1625  return 0;
1626 }
#define PGTYPES_NUM_OVERFLOW
Definition: pgtypes_error.h:3
#define PGTYPES_NUM_UNDERFLOW
Definition: pgtypes_error.h:6
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
char * PGTYPESnumeric_to_asc(numeric *num, int dscale)
Definition: numeric.c:428

Variable Documentation

sqlda_t* inp_sqlda

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

sqlda_t * outp_sqlda

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

Referenced by main().

sqlda_t * outp_sqlda1

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

Referenced by main().