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 *)
 
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

◆ 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.

Referenced by main().

◆ 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.

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().

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(
159 #ifdef _WIN32
160  "name sqlda descriptor: '%s' value %I64d\n",
161 #else
162  "name sqlda descriptor: '%s' value %lld\n",
163 #endif
164  sqlda->sqlvar[i].sqlname.data, *(long long int *)sqlda->sqlvar[i].sqldata);
165  break;
166  case ECPGt_double:
167  printf("name sqlda descriptor: '%s' value %f\n", sqlda->sqlvar[i].sqlname.data, *(double *)sqlda->sqlvar[i].sqldata);
168  break;
169  case ECPGt_numeric:
170  {
171  char *val;
172 
173  val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1);
174  printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val);
175  PGTYPESchar_free(val);
176  break;
177  }
178  }
179  }
180 }
struct sqlvar_struct sqlvar[1]
Definition: sqlda-native.h:40
#define printf(...)
Definition: port.h:199
char * sqldata
Definition: sqlda-native.h:28
void PGTYPESchar_free(char *ptr)
Definition: common.c:145
char * PGTYPESnumeric_to_asc(numeric *, int)
Definition: numeric.c:347
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:664

◆ main()

int main ( void  )

Definition at line 183 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, outp_sqlda, outp_sqlda1, printf, sqlca, sqlvar_struct::sqldata, sqlda_struct::sqln, sqlvar_struct::sqltype, and sqlda_struct::sqlvar.

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

◆ PGTYPESdecimal_free()

void PGTYPESdecimal_free ( decimal )

Definition at line 396 of file numeric.c.

References free.

397 {
398  free(var);
399 }
#define free(a)
Definition: header.h:65

◆ PGTYPESdecimal_new()

decimal* PGTYPESdecimal_new ( void  )

Definition at line 63 of file numeric.c.

References pgtypes_alloc().

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

◆ PGTYPESnumeric_add()

int PGTYPESnumeric_add ( numeric ,
numeric ,
numeric  
)

Definition at line 641 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().

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

◆ PGTYPESnumeric_cmp()

int PGTYPESnumeric_cmp ( numeric ,
numeric  
)

Definition at line 1286 of file numeric.c.

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

1287 {
1288  /* use cmp_abs function to calculate the result */
1289 
1290  /* both are positive: normal comparison with cmp_abs */
1291  if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_POS)
1292  return cmp_abs(var1, var2);
1293 
1294  /* both are negative: return the inverse of the normal comparison */
1295  if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_NEG)
1296  {
1297  /*
1298  * instead of inverting the result, we invert the parameter ordering
1299  */
1300  return cmp_abs(var2, var1);
1301  }
1302 
1303  /* one is positive, one is negative: trivial */
1304  if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_NEG)
1305  return 1;
1306  if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_POS)
1307  return -1;
1308 
1309  errno = PGTYPES_NUM_BAD_NUMERIC;
1310  return INT_MAX;
1311 
1312 }
#define NUMERIC_POS
Definition: numeric.c:167
#define NUMERIC_NEG
Definition: numeric.c:168
static int cmp_abs(numeric *var1, numeric *var2)
Definition: numeric.c:411
#define PGTYPES_NUM_BAD_NUMERIC
Definition: pgtypes_error.h:4

◆ PGTYPESnumeric_copy()

int PGTYPESnumeric_copy ( numeric ,
numeric  
)

Definition at line 1394 of file numeric.c.

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

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

1395 {
1396  int i;
1397 
1398  if (dst == NULL)
1399  return -1;
1400  zero_var(dst);
1401 
1402  dst->weight = src->weight;
1403  dst->rscale = src->rscale;
1404  dst->dscale = src->dscale;
1405  dst->sign = src->sign;
1406 
1407  if (alloc_var(dst, src->ndigits) != 0)
1408  return -1;
1409 
1410  for (i = 0; i < src->ndigits; i++)
1411  dst->digits[i] = src->digits[i];
1412 
1413  return 0;
1414 }
static void zero_var(numeric *var)
Definition: numeric.c:378
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:33
int i

◆ PGTYPESnumeric_div()

int PGTYPESnumeric_div ( numeric ,
numeric ,
numeric  
)

Definition at line 1057 of file numeric.c.

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

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

◆ PGTYPESnumeric_free()

void PGTYPESnumeric_free ( numeric )

Definition at line 389 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().

390 {
391  digitbuf_free(var->buf);
392  free(var);
393 }
#define free(a)
Definition: header.h:65
#define digitbuf_free(buf)
Definition: numeric.c:19

◆ PGTYPESnumeric_from_asc()

numeric* PGTYPESnumeric_from_asc ( char *  ,
char **   
)

Definition at line 325 of file numeric.c.

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

Referenced by PGTYPESnumeric_from_double().

326 {
327  numeric *value = (numeric *) pgtypes_alloc(sizeof(numeric));
328  int ret;
329 
330  char *realptr;
331  char **ptr = (endptr != NULL) ? endptr : &realptr;
332 
333  if (!value)
334  return NULL;
335 
336  ret = set_var_from_str(str, ptr, value);
337  if (ret)
338  {
339  PGTYPESnumeric_free(value);
340  return NULL;
341  }
342 
343  return value;
344 }
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:389
char * pgtypes_alloc(long size)
Definition: common.c:10
static struct @143 value
static int set_var_from_str(char *str, char **ptr, numeric *dest)
Definition: numeric.c:82

◆ PGTYPESnumeric_from_decimal()

int PGTYPESnumeric_from_decimal ( decimal ,
numeric  
)

Definition at line 1571 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().

1572 {
1573  int i;
1574 
1575  zero_var(dst);
1576 
1577  dst->weight = src->weight;
1578  dst->rscale = src->rscale;
1579  dst->dscale = src->dscale;
1580  dst->sign = src->sign;
1581 
1582  if (alloc_var(dst, src->ndigits) != 0)
1583  return -1;
1584 
1585  for (i = 0; i < src->ndigits; i++)
1586  dst->digits[i] = src->digits[i];
1587 
1588  return 0;
1589 }
static void zero_var(numeric *var)
Definition: numeric.c:378
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:33
int i

◆ PGTYPESnumeric_from_double()

int PGTYPESnumeric_from_double ( double  ,
numeric  
)

Definition at line 1417 of file numeric.c.

References i, PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), and sprintf.

1418 {
1419  char buffer[DBL_DIG + 100];
1420  numeric *tmp;
1421  int i;
1422 
1423  if (sprintf(buffer, "%.*g", DBL_DIG, d) <= 0)
1424  return -1;
1425 
1426  if ((tmp = PGTYPESnumeric_from_asc(buffer, NULL)) == NULL)
1427  return -1;
1428  i = PGTYPESnumeric_copy(tmp, dst);
1429  PGTYPESnumeric_free(tmp);
1430  if (i != 0)
1431  return -1;
1432 
1433  errno = 0;
1434  return 0;
1435 }
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:389
#define sprintf
Definition: port.h:195
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
Definition: numeric.c:1394
numeric * PGTYPESnumeric_from_asc(char *str, char **endptr)
Definition: numeric.c:325
int i

◆ PGTYPESnumeric_from_int()

int PGTYPESnumeric_from_int ( signed  int,
numeric  
)

Definition at line 1315 of file numeric.c.

References PGTYPESnumeric_from_long().

1316 {
1317  /* implicit conversion */
1318  signed long int long_int = int_val;
1319 
1320  return PGTYPESnumeric_from_long(long_int, var);
1321 }
int PGTYPESnumeric_from_long(signed long int long_val, numeric *var)
Definition: numeric.c:1324

◆ PGTYPESnumeric_from_long()

int PGTYPESnumeric_from_long ( signed long  int,
numeric  
)

Definition at line 1324 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().

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

◆ PGTYPESnumeric_mul()

int PGTYPESnumeric_mul ( numeric ,
numeric ,
numeric  
)

Definition at line 900 of file numeric.c.

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

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

◆ PGTYPESnumeric_new()

numeric* PGTYPESnumeric_new ( void  )

Definition at line 46 of file numeric.c.

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

Referenced by numericvar_to_double(), and PGTYPESnumeric_to_asc().

47 {
48  numeric *var;
49 
50  if ((var = (numeric *) pgtypes_alloc(sizeof(numeric))) == NULL)
51  return NULL;
52 
53  if (alloc_var(var, 0) < 0)
54  {
55  free(var);
56  return NULL;
57  }
58 
59  return var;
60 }
char * pgtypes_alloc(long size)
Definition: common.c:10
static int alloc_var(numeric *var, int ndigits)
Definition: numeric.c:33
#define free(a)
Definition: header.h:65

◆ PGTYPESnumeric_sub()

int PGTYPESnumeric_sub ( numeric ,
numeric ,
numeric  
)

Definition at line 769 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().

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

◆ PGTYPESnumeric_to_asc()

char* PGTYPESnumeric_to_asc ( numeric ,
int   
)

Definition at line 347 of file numeric.c.

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

Referenced by dump_sqlda(), and PGTYPESnumeric_to_long().

348 {
349  numeric *numcopy = PGTYPESnumeric_new();
350  char *s;
351 
352  if (numcopy == NULL)
353  return NULL;
354 
355  if (PGTYPESnumeric_copy(num, numcopy) < 0)
356  {
357  PGTYPESnumeric_free(numcopy);
358  return NULL;
359  }
360 
361  if (dscale < 0)
362  dscale = num->dscale;
363 
364  /* get_str_from_var may change its argument */
365  s = get_str_from_var(numcopy, dscale);
366  PGTYPESnumeric_free(numcopy);
367  return s;
368 }
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:46
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:389
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
Definition: numeric.c:1394
static char * get_str_from_var(numeric *var, int dscale)
Definition: numeric.c:230

◆ PGTYPESnumeric_to_decimal()

int PGTYPESnumeric_to_decimal ( numeric ,
decimal  
)

Definition at line 1548 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.

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

◆ PGTYPESnumeric_to_double()

int PGTYPESnumeric_to_double ( numeric ,
double *   
)

Definition at line 1489 of file numeric.c.

References numericvar_to_double().

1490 {
1491  double tmp;
1492 
1493  if (numericvar_to_double(nv, &tmp) != 0)
1494  return -1;
1495  *dp = tmp;
1496  return 0;
1497 }
static int numericvar_to_double(numeric *var, double *dp)
Definition: numeric.c:1438

◆ PGTYPESnumeric_to_int()

int PGTYPESnumeric_to_int ( numeric ,
int *   
)

Definition at line 1500 of file numeric.c.

References i, PGTYPES_NUM_OVERFLOW, and PGTYPESnumeric_to_long().

1501 {
1502  long l;
1503  int i;
1504 
1505  if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
1506  return i;
1507 
1508  if (l < -INT_MAX || l > INT_MAX)
1509  {
1510  errno = PGTYPES_NUM_OVERFLOW;
1511  return -1;
1512  }
1513 
1514  *ip = (int) l;
1515  return 0;
1516 }
#define PGTYPES_NUM_OVERFLOW
Definition: pgtypes_error.h:3
int i
int PGTYPESnumeric_to_long(numeric *nv, long *lp)
Definition: numeric.c:1519

◆ PGTYPESnumeric_to_long()

int PGTYPESnumeric_to_long ( numeric ,
long *   
)

Definition at line 1519 of file numeric.c.

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

Referenced by PGTYPESnumeric_to_int().

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

Variable Documentation

◆ inp_sqlda

sqlda_t* inp_sqlda

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

◆ 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().