#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.
1.7.1