#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "sqlda-native.h"
Go to the source code of this file.
#define DECSIZE 30 |
Definition at line 62 of file sql-sqlda.c.
#define ECPGdebug | ( | X, | ||
Y | ||||
) | ECPGdebug((X)+100,(Y)) |
Definition at line 7 of file sql-sqlda.c.
#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 unsigned char NumericDigit |
Definition at line 64 of file sql-sqlda.c.
typedef struct sqlda_struct sqlda_t |
Definition at line 40 of file sql-sqlda.c.
typedef struct sqlvar_struct sqlvar_t |
Definition at line 39 of file sql-sqlda.c.
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().
{ int i; if (sqlda == NULL) { printf("dump_sqlda called with NULL sqlda\n"); return; } for (i = 0; i < sqlda->sqld; i++) { if (sqlda->sqlvar[i].sqlind && *(sqlda->sqlvar[i].sqlind) == -1) printf("name sqlda descriptor: '%s' value NULL'\n", sqlda->sqlvar[i].sqlname.data); else switch (sqlda->sqlvar[i].sqltype) { case ECPGt_char: printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname.data, sqlda->sqlvar[i].sqldata); break; case ECPGt_int: printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname.data, *(int *)sqlda->sqlvar[i].sqldata); break; case ECPGt_double: printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname.data, *(double *)sqlda->sqlvar[i].sqldata); break; case ECPGt_numeric: { char *val; val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1); printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val); free(val); break; } } } }
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_NO_INDICATOR, ECPGt_sqlda, ECPGtrans(), free, malloc, NULL, sqlca, sqlvar_struct::sqldata, sqlda_struct::sqln, sqlvar_struct::sqltype, and sqlda_struct::sqlvar.
{ /* exec sql begin declare section */ #line 59 "sqlda.pgc" char * stmt1 = "SELECT * FROM t1" ; #line 60 "sqlda.pgc" char * stmt2 = "SELECT * FROM t1 WHERE id = ?" ; #line 61 "sqlda.pgc" int rec ; #line 62 "sqlda.pgc" int id ; /* exec sql end declare section */ #line 63 "sqlda.pgc" char msg[128]; ECPGdebug(1, stderr); strcpy(msg, "connect"); { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , "regress1", 0); #line 70 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 70 "sqlda.pgc" strcpy(msg, "set"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT); #line 73 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 73 "sqlda.pgc" strcpy(msg, "create"); { 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); #line 81 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 81 "sqlda.pgc" strcpy(msg, "insert"); { 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); #line 87 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 87 "sqlda.pgc" strcpy(msg, "commit"); { ECPGtrans(__LINE__, NULL, "commit"); #line 90 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 90 "sqlda.pgc" /* SQLDA test for getting all records from a table */ outp_sqlda = NULL; strcpy(msg, "prepare"); { ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1); #line 97 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 97 "sqlda.pgc" strcpy(msg, "declare"); /* declare mycur1 cursor for $1 */ #line 100 "sqlda.pgc" strcpy(msg, "open"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 103 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 103 "sqlda.pgc" /* exec sql whenever not found break ; */ #line 105 "sqlda.pgc" rec = 0; while (1) { strcpy(msg, "fetch"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 111 "sqlda.pgc" if (sqlca.sqlcode == ECPG_NOT_FOUND) break; #line 111 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 111 "sqlda.pgc" printf("FETCH RECORD %d\n", ++rec); dump_sqlda(outp_sqlda); } /* exec sql whenever not found continue ; */ #line 117 "sqlda.pgc" strcpy(msg, "close"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT); #line 120 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 120 "sqlda.pgc" strcpy(msg, "deallocate"); { ECPGdeallocate(__LINE__, 0, NULL, "st_id1"); #line 123 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 123 "sqlda.pgc" free(outp_sqlda); /* SQLDA test for getting ALL records into the sqlda list */ outp_sqlda = NULL; strcpy(msg, "prepare"); { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt1); #line 132 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 132 "sqlda.pgc" strcpy(msg, "declare"); /* declare mycur2 cursor for $1 */ #line 135 "sqlda.pgc" strcpy(msg, "open"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 138 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 138 "sqlda.pgc" strcpy(msg, "fetch"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 141 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 141 "sqlda.pgc" outp_sqlda1 = outp_sqlda; rec = 0; while (outp_sqlda1) { sqlda_t *ptr; printf("FETCH RECORD %d\n", ++rec); dump_sqlda(outp_sqlda1); ptr = outp_sqlda1; outp_sqlda1 = outp_sqlda1->desc_next; free(ptr); } strcpy(msg, "close"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT); #line 157 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 157 "sqlda.pgc" strcpy(msg, "deallocate"); { ECPGdeallocate(__LINE__, 0, NULL, "st_id2"); #line 160 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 160 "sqlda.pgc" /* SQLDA test for getting one record using an input descriptor */ /* * Input sqlda has to be built manually * sqlda_t contains 1 sqlvar_t structure already. */ inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t)); memset(inp_sqlda, 0, sizeof(sqlda_t)); inp_sqlda->sqln = 1; inp_sqlda->sqlvar[0].sqltype = ECPGt_int; inp_sqlda->sqlvar[0].sqldata = (char *)&id; printf("EXECUTE RECORD 4\n"); id = 4; outp_sqlda = NULL; strcpy(msg, "prepare"); { ECPGprepare(__LINE__, NULL, 0, "st_id3", stmt2); #line 182 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 182 "sqlda.pgc" strcpy(msg, "execute"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "st_id3", ECPGt_sqlda, &inp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 185 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 185 "sqlda.pgc" dump_sqlda(outp_sqlda); strcpy(msg, "deallocate"); { ECPGdeallocate(__LINE__, 0, NULL, "st_id3"); #line 190 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 190 "sqlda.pgc" free(inp_sqlda); free(outp_sqlda); /* SQLDA test for getting one record using an input descriptor * on a named connection */ { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , "con2", 0); #line 199 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 199 "sqlda.pgc" /* * Input sqlda has to be built manually * sqlda_t contains 1 sqlvar_t structure already. */ inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t)); memset(inp_sqlda, 0, sizeof(sqlda_t)); inp_sqlda->sqln = 1; inp_sqlda->sqlvar[0].sqltype = ECPGt_int; inp_sqlda->sqlvar[0].sqldata = (char *)&id; printf("EXECUTE RECORD 4\n"); id = 4; outp_sqlda = NULL; strcpy(msg, "prepare"); { ECPGprepare(__LINE__, "con2", 0, "st_id4", stmt2); #line 219 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 219 "sqlda.pgc" strcpy(msg, "execute"); { ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_execute, "st_id4", ECPGt_sqlda, &inp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 222 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 222 "sqlda.pgc" dump_sqlda(outp_sqlda); strcpy(msg, "commit"); { ECPGtrans(__LINE__, "con2", "commit"); #line 227 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 227 "sqlda.pgc" strcpy(msg, "deallocate"); { ECPGdeallocate(__LINE__, 0, NULL, "st_id4"); #line 230 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 230 "sqlda.pgc" free(inp_sqlda); free(outp_sqlda); strcpy(msg, "disconnect"); { ECPGdisconnect(__LINE__, "con2"); #line 236 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 236 "sqlda.pgc" /* End test */ strcpy(msg, "drop"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT); #line 241 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 241 "sqlda.pgc" strcpy(msg, "commit"); { ECPGtrans(__LINE__, NULL, "commit"); #line 244 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 244 "sqlda.pgc" strcpy(msg, "disconnect"); { ECPGdisconnect(__LINE__, "CURRENT"); #line 247 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} #line 247 "sqlda.pgc" return (0); }
void PGTYPESdecimal_free | ( | decimal * | ) |
decimal* PGTYPESdecimal_new | ( | void | ) |
Definition at line 143 of file numeric.c.
References NULL, and pgtypes_alloc().
Definition at line 718 of file numeric.c.
References add_abs(), cmp_abs(), numeric::dscale, Max, NUMERIC_POS, numeric::rscale, numeric::sign, sub_abs(), and zero_var().
{ /* * Decide on the signs of the two variables what to do */ if (var1->sign == NUMERIC_POS) { if (var2->sign == NUMERIC_POS) { /* * Both are positive result = +(ABS(var1) + ABS(var2)) */ if (add_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_POS; } else { /* * var1 is positive, var2 is negative Must compare absolute values */ switch (cmp_abs(var1, var2)) { case 0: /* ---------- * ABS(var1) == ABS(var2) * result = ZERO * ---------- */ zero_var(result); result->rscale = Max(var1->rscale, var2->rscale); result->dscale = Max(var1->dscale, var2->dscale); break; case 1: /* ---------- * ABS(var1) > ABS(var2) * result = +(ABS(var1) - ABS(var2)) * ---------- */ if (sub_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_POS; break; case -1: /* ---------- * ABS(var1) < ABS(var2) * result = -(ABS(var2) - ABS(var1)) * ---------- */ if (sub_abs(var2, var1, result) != 0) return -1; result->sign = NUMERIC_NEG; break; } } } else { if (var2->sign == NUMERIC_POS) { /* ---------- * var1 is negative, var2 is positive * Must compare absolute values * ---------- */ switch (cmp_abs(var1, var2)) { case 0: /* ---------- * ABS(var1) == ABS(var2) * result = ZERO * ---------- */ zero_var(result); result->rscale = Max(var1->rscale, var2->rscale); result->dscale = Max(var1->dscale, var2->dscale); break; case 1: /* ---------- * ABS(var1) > ABS(var2) * result = -(ABS(var1) - ABS(var2)) * ---------- */ if (sub_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_NEG; break; case -1: /* ---------- * ABS(var1) < ABS(var2) * result = +(ABS(var2) - ABS(var1)) * ---------- */ if (sub_abs(var2, var1, result) != 0) return -1; result->sign = NUMERIC_POS; break; } } else { /* ---------- * Both are negative * result = -(ABS(var1) + ABS(var2)) * ---------- */ if (add_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_NEG; } } return 0; }
Definition at line 1363 of file numeric.c.
References cmp_abs(), NUMERIC_NEG, NUMERIC_POS, and numeric::sign.
{ /* use cmp_abs function to calculate the result */ /* both are positive: normal comparation with cmp_abs */ if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_POS) return cmp_abs(var1, var2); /* both are negative: return the inverse of the normal comparation */ if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_NEG) { /* * instead of inverting the result, we invert the paramter ordering */ return cmp_abs(var2, var1); } /* one is positive, one is negative: trivial */ if (var1->sign == NUMERIC_POS && var2->sign == NUMERIC_NEG) return 1; if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_POS) return -1; errno = PGTYPES_NUM_BAD_NUMERIC; return INT_MAX; }
Definition at line 1472 of file numeric.c.
References alloc_var(), numeric::digits, numeric::dscale, i, numeric::ndigits, NULL, numeric::rscale, numeric::sign, numeric::weight, and zero_var().
Definition at line 1134 of file numeric.c.
References buf, numeric::buf, cmp_abs(), digitbuf_alloc, digitbuf_free, digits, numeric::digits, numeric::dscale, i, init_var, numeric::ndigits, NULL, numeric::rscale, select_div_scale(), numeric::sign, sub_abs(), numeric::weight, and zero_var().
{ NumericDigit *res_digits; int res_ndigits; int res_sign; int res_weight; numeric dividend; numeric divisor[10]; int ndigits_tmp; int weight_tmp; int rscale_tmp; int ri; int i; long guess; long first_have; long first_div; int first_nextdigit; int stat = 0; int rscale; int res_dscale = select_div_scale(var1, var2, &rscale); int err = -1; NumericDigit *tmp_buf; /* * First of all division by zero check */ ndigits_tmp = var2->ndigits + 1; if (ndigits_tmp == 1) { errno = PGTYPES_NUM_DIVIDE_ZERO; return -1; } /* * Determine the result sign, weight and number of digits to calculate */ if (var1->sign == var2->sign) res_sign = NUMERIC_POS; else res_sign = NUMERIC_NEG; res_weight = var1->weight - var2->weight + 1; res_ndigits = rscale + res_weight; if (res_ndigits <= 0) res_ndigits = 1; /* * Now result zero check */ if (var1->ndigits == 0) { zero_var(result); result->rscale = rscale; return 0; } /* * Initialize local variables */ init_var(÷nd); for (i = 1; i < 10; i++) init_var(&divisor[i]); /* * Make a copy of the divisor which has one leading zero digit */ divisor[1].ndigits = ndigits_tmp; divisor[1].rscale = var2->ndigits; divisor[1].sign = NUMERIC_POS; divisor[1].buf = digitbuf_alloc(ndigits_tmp); if (divisor[1].buf == NULL) goto done; divisor[1].digits = divisor[1].buf; divisor[1].digits[0] = 0; memcpy(&(divisor[1].digits[1]), var2->digits, ndigits_tmp - 1); /* * Make a copy of the dividend */ dividend.ndigits = var1->ndigits; dividend.weight = 0; dividend.rscale = var1->ndigits; dividend.sign = NUMERIC_POS; dividend.buf = digitbuf_alloc(var1->ndigits); if (dividend.buf == NULL) goto done; dividend.digits = dividend.buf; memcpy(dividend.digits, var1->digits, var1->ndigits); /* * Setup the result. Do the allocation in a temporary buffer first, so we * don't free result->buf unless we have successfully allocated a buffer * to replace it with. */ tmp_buf = digitbuf_alloc(res_ndigits + 2); if (tmp_buf == NULL) goto done; digitbuf_free(result->buf); result->buf = tmp_buf; res_digits = result->buf; result->digits = res_digits; result->ndigits = res_ndigits; result->weight = res_weight; result->rscale = rscale; result->sign = res_sign; res_digits[0] = 0; first_div = divisor[1].digits[1] * 10; if (ndigits_tmp > 2) first_div += divisor[1].digits[2]; first_have = 0; first_nextdigit = 0; weight_tmp = 1; rscale_tmp = divisor[1].rscale; for (ri = 0; ri <= res_ndigits; ri++) { first_have = first_have * 10; if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits) first_have += dividend.digits[first_nextdigit]; first_nextdigit++; guess = (first_have * 10) / first_div + 1; if (guess > 9) guess = 9; while (guess > 0) { if (divisor[guess].buf == NULL) { int i; long sum = 0; memcpy(&divisor[guess], &divisor[1], sizeof(numeric)); divisor[guess].buf = digitbuf_alloc(divisor[guess].ndigits); if (divisor[guess].buf == NULL) goto done; divisor[guess].digits = divisor[guess].buf; for (i = divisor[1].ndigits - 1; i >= 0; i--) { sum += divisor[1].digits[i] * guess; divisor[guess].digits[i] = sum % 10; sum /= 10; } } divisor[guess].weight = weight_tmp; divisor[guess].rscale = rscale_tmp; stat = cmp_abs(÷nd, &divisor[guess]); if (stat >= 0) break; guess--; } res_digits[ri + 1] = guess; if (stat == 0) { ri++; break; } weight_tmp--; rscale_tmp++; if (guess == 0) continue; if (sub_abs(÷nd, &divisor[guess], ÷nd) != 0) goto done; first_nextdigit = dividend.weight - weight_tmp; first_have = 0; if (first_nextdigit >= 0 && first_nextdigit < dividend.ndigits) first_have = dividend.digits[first_nextdigit]; first_nextdigit++; } result->ndigits = ri + 1; if (ri == res_ndigits + 1) { int carry = (res_digits[ri] > 4) ? 1 : 0; result->ndigits = ri; res_digits[ri] = 0; while (carry && ri > 0) { carry += res_digits[--ri]; res_digits[ri] = carry % 10; carry /= 10; } } while (result->ndigits > 0 && *(result->digits) == 0) { (result->digits)++; (result->weight)--; (result->ndigits)--; } while (result->ndigits > 0 && result->digits[result->ndigits - 1] == 0) (result->ndigits)--; if (result->ndigits == 0) result->sign = NUMERIC_POS; result->dscale = res_dscale; err = 0; /* if we've made it this far, return success */ done: /* * Tidy up */ if (dividend.buf != NULL) digitbuf_free(dividend.buf); for (i = 1; i < 10; i++) { if (divisor[i].buf != NULL) digitbuf_free(divisor[i].buf); } return err; }
void PGTYPESnumeric_free | ( | numeric * | ) |
Definition at line 466 of file numeric.c.
References numeric::buf, digitbuf_free, and free.
{ digitbuf_free(var->buf); free(var); }
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.
{ numeric *value = (numeric *) pgtypes_alloc(sizeof(numeric)); int ret; char *realptr; char **ptr = (endptr != NULL) ? endptr : &realptr; if (!value) return (NULL); ret = set_var_from_str(str, ptr, value); if (ret) { PGTYPESnumeric_free(value); return (NULL); } return (value); }
Definition at line 1646 of file numeric.c.
References alloc_var(), decimal::digits, numeric::digits, decimal::dscale, numeric::dscale, i, decimal::ndigits, decimal::rscale, numeric::rscale, decimal::sign, numeric::sign, decimal::weight, numeric::weight, and zero_var().
int PGTYPESnumeric_from_double | ( | double | , | |
numeric * | ||||
) |
Definition at line 1495 of file numeric.c.
References i, NULL, PGTYPESnumeric_copy(), PGTYPESnumeric_free(), and PGTYPESnumeric_from_asc().
{ char buffer[100]; numeric *tmp; int i; if (sprintf(buffer, "%f", d) == 0) return -1; if ((tmp = PGTYPESnumeric_from_asc(buffer, NULL)) == NULL) return -1; i = PGTYPESnumeric_copy(tmp, dst); PGTYPESnumeric_free(tmp); if (i != 0) return -1; errno = 0; return 0; }
int PGTYPESnumeric_from_int | ( | signed | int, | |
numeric * | ||||
) |
Definition at line 1393 of file numeric.c.
References PGTYPESnumeric_from_long().
{ /* implicit conversion */ signed long int long_int = int_val; return PGTYPESnumeric_from_long(long_int, var); }
int PGTYPESnumeric_from_long | ( | signed long | int, | |
numeric * | ||||
) |
Definition at line 1402 of file numeric.c.
References alloc_var(), numeric::digits, numeric::dscale, i, numeric::rscale, numeric::sign, and numeric::weight.
{ /* calculate the size of the long int number */ /* a number n needs log_10 n digits */ /* * however we multiply by 10 each time and compare instead of calculating * the logarithm */ int size = 0; int i; signed long int abs_long_val = long_val; signed long int extract; signed long int reach_limit; if (abs_long_val < 0) { abs_long_val *= -1; var->sign = NUMERIC_NEG; } else var->sign = NUMERIC_POS; reach_limit = 1; do { size++; reach_limit *= 10; } while (reach_limit - 1 < abs_long_val && reach_limit <= LONG_MAX / 10); if (reach_limit > LONG_MAX / 10) { /* add the first digit and a .0 */ size += 2; } else { /* always add a .0 */ size++; reach_limit /= 10; } if (alloc_var(var, size) < 0) return -1; var->rscale = 1; var->dscale = 1; var->weight = size - 2; i = 0; do { extract = abs_long_val - (abs_long_val % reach_limit); var->digits[i] = extract / reach_limit; abs_long_val -= extract; i++; reach_limit /= 10; /* * we can abandon if abs_long_val reaches 0, because the memory is * initialized properly and filled with '0', so converting 10000 in * only one step is no problem */ } while (abs_long_val > 0); return 0; }
Definition at line 977 of file numeric.c.
References numeric::buf, digitbuf_alloc, digitbuf_free, numeric::digits, numeric::dscale, i, numeric::ndigits, NULL, numeric::rscale, numeric::sign, and numeric::weight.
{ NumericDigit *res_buf; NumericDigit *res_digits; int res_ndigits; int res_weight; int res_sign; int i, ri, i1, i2; long sum = 0; int global_rscale = var1->rscale + var2->rscale; res_weight = var1->weight + var2->weight + 2; res_ndigits = var1->ndigits + var2->ndigits + 1; if (var1->sign == var2->sign) res_sign = NUMERIC_POS; else res_sign = NUMERIC_NEG; if ((res_buf = digitbuf_alloc(res_ndigits)) == NULL) return -1; res_digits = res_buf; memset(res_digits, 0, res_ndigits); ri = res_ndigits; for (i1 = var1->ndigits - 1; i1 >= 0; i1--) { sum = 0; i = --ri; for (i2 = var2->ndigits - 1; i2 >= 0; i2--) { sum += res_digits[i] + var1->digits[i1] * var2->digits[i2]; res_digits[i--] = sum % 10; sum /= 10; } res_digits[i] = sum; } i = res_weight + global_rscale + 2; if (i >= 0 && i < res_ndigits) { sum = (res_digits[i] > 4) ? 1 : 0; res_ndigits = i; i--; while (sum) { sum += res_digits[i]; res_digits[i--] = sum % 10; sum /= 10; } } while (res_ndigits > 0 && *res_digits == 0) { res_digits++; res_weight--; res_ndigits--; } while (res_ndigits > 0 && res_digits[res_ndigits - 1] == 0) res_ndigits--; if (res_ndigits == 0) { res_sign = NUMERIC_POS; res_weight = 0; } digitbuf_free(result->buf); result->buf = res_buf; result->digits = res_digits; result->ndigits = res_ndigits; result->weight = res_weight; result->rscale = global_rscale; result->sign = res_sign; result->dscale = var1->dscale + var2->dscale; return 0; }
numeric* PGTYPESnumeric_new | ( | void | ) |
Definition at line 126 of file numeric.c.
References alloc_var(), free, NULL, and pgtypes_alloc().
Definition at line 846 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().
{ /* * Decide on the signs of the two variables what to do */ if (var1->sign == NUMERIC_POS) { if (var2->sign == NUMERIC_NEG) { /* ---------- * var1 is positive, var2 is negative * result = +(ABS(var1) + ABS(var2)) * ---------- */ if (add_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_POS; } else { /* ---------- * Both are positive * Must compare absolute values * ---------- */ switch (cmp_abs(var1, var2)) { case 0: /* ---------- * ABS(var1) == ABS(var2) * result = ZERO * ---------- */ zero_var(result); result->rscale = Max(var1->rscale, var2->rscale); result->dscale = Max(var1->dscale, var2->dscale); break; case 1: /* ---------- * ABS(var1) > ABS(var2) * result = +(ABS(var1) - ABS(var2)) * ---------- */ if (sub_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_POS; break; case -1: /* ---------- * ABS(var1) < ABS(var2) * result = -(ABS(var2) - ABS(var1)) * ---------- */ if (sub_abs(var2, var1, result) != 0) return -1; result->sign = NUMERIC_NEG; break; } } } else { if (var2->sign == NUMERIC_NEG) { /* ---------- * Both are negative * Must compare absolute values * ---------- */ switch (cmp_abs(var1, var2)) { case 0: /* ---------- * ABS(var1) == ABS(var2) * result = ZERO * ---------- */ zero_var(result); result->rscale = Max(var1->rscale, var2->rscale); result->dscale = Max(var1->dscale, var2->dscale); break; case 1: /* ---------- * ABS(var1) > ABS(var2) * result = -(ABS(var1) - ABS(var2)) * ---------- */ if (sub_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_NEG; break; case -1: /* ---------- * ABS(var1) < ABS(var2) * result = +(ABS(var2) - ABS(var1)) * ---------- */ if (sub_abs(var2, var1, result) != 0) return -1; result->sign = NUMERIC_POS; break; } } else { /* ---------- * var1 is negative, var2 is positive * result = -(ABS(var1) + ABS(var2)) * ---------- */ if (add_abs(var1, var2, result) != 0) return -1; result->sign = NUMERIC_NEG; } } return 0; }
char* PGTYPESnumeric_to_asc | ( | numeric * | , | |
int | ||||
) |
Definition at line 428 of file numeric.c.
References numeric::dscale, get_str_from_var(), PGTYPESnumeric_copy(), PGTYPESnumeric_free(), and PGTYPESnumeric_new().
{ numeric *numcopy = PGTYPESnumeric_new(); char *s; if (dscale < 0) dscale = num->dscale; if (PGTYPESnumeric_copy(num, numcopy) < 0) { PGTYPESnumeric_free(numcopy); return NULL; } /* get_str_from_var may change its argument */ s = get_str_from_var(numcopy, dscale); PGTYPESnumeric_free(numcopy); return (s); }
Definition at line 1623 of file numeric.c.
References DECSIZE, numeric::digits, decimal::digits, numeric::dscale, decimal::dscale, i, decimal::ndigits, numeric::ndigits, numeric::rscale, decimal::rscale, numeric::sign, decimal::sign, numeric::weight, and decimal::weight.
int PGTYPESnumeric_to_double | ( | numeric * | , | |
double * | ||||
) |
Definition at line 1564 of file numeric.c.
References numericvar_to_double().
{ double tmp; if (numericvar_to_double(nv, &tmp) != 0) return -1; *dp = tmp; return 0; }
int PGTYPESnumeric_to_int | ( | numeric * | , | |
int * | ||||
) |
Definition at line 1575 of file numeric.c.
References i, and PGTYPESnumeric_to_long().
{ long l; int i; if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0) return i; if (l < -INT_MAX || l > INT_MAX) { errno = PGTYPES_NUM_OVERFLOW; return -1; } *ip = (int) l; return 0; }
int PGTYPESnumeric_to_long | ( | numeric * | , | |
long * | ||||
) |
Definition at line 1594 of file numeric.c.
References free, NULL, and PGTYPESnumeric_to_asc().
{ char *s = PGTYPESnumeric_to_asc(nv, 0); char *endptr; if (s == NULL) return -1; errno = 0; *lp = strtol(s, &endptr, 10); if (endptr == s) { /* this should not happen actually */ free(s); return -1; } free(s); if (errno == ERANGE) { if (*lp == LONG_MIN) errno = PGTYPES_NUM_UNDERFLOW; else errno = PGTYPES_NUM_OVERFLOW; return -1; } return 0; }
Definition at line 126 of file sql-sqlda.c.
Definition at line 126 of file sql-sqlda.c.
Definition at line 126 of file sql-sqlda.c.