📄 informix.c
字号:
/* $PostgreSQL: pgsql/src/interfaces/ecpg/compatlib/informix.c,v 1.54 2008/01/08 01:14:52 tgl Exp $ */#define POSTGRES_ECPG_INTERNAL#include "postgres_fe.h"#include <math.h>#include <ctype.h>#include <limits.h>#include <ecpgtype.h>#include <ecpg_informix.h>#include <pgtypes_error.h>#include <pgtypes_date.h>#include <pgtypes_numeric.h>#include <sqltypes.h>#include <sqlca.h>#include <ecpgerrno.h>static intdeccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *)){ numeric *a1, *a2; int i; if ((a1 = PGTYPESnumeric_new()) == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if ((a2 = PGTYPESnumeric_new()) == NULL) { PGTYPESnumeric_free(a1); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg1, a1) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg2, a2) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return ECPG_INFORMIX_OUT_OF_MEMORY; } i = (*ptr) (a1, a2); PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return (i);}static intdeccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *)){ numeric *a1, *a2, *nres; int i; /* * we must NOT set the result to NULL here because it may be the same * variable as one of the arguments */ if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2)) return 0; if ((a1 = PGTYPESnumeric_new()) == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if ((a2 = PGTYPESnumeric_new()) == NULL) { PGTYPESnumeric_free(a1); return ECPG_INFORMIX_OUT_OF_MEMORY; } if ((nres = PGTYPESnumeric_new()) == NULL) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg1, a1) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (PGTYPESnumeric_from_decimal(arg2, a2) != 0) { PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } i = (*ptr) (a1, a2, nres); if (i == 0) /* No error */ { /* set the result to null in case it errors out later */ rsetnull(CDECIMALTYPE, (char *) result); PGTYPESnumeric_to_decimal(nres, result); } PGTYPESnumeric_free(nres); PGTYPESnumeric_free(a1); PGTYPESnumeric_free(a2); return (i);}/* we start with the numeric functions */intdecadd(decimal *arg1, decimal *arg2, decimal *sum){ errno = 0; deccall3(arg1, arg2, sum, PGTYPESnumeric_add); if (errno == PGTYPES_NUM_OVERFLOW) return ECPG_INFORMIX_NUM_OVERFLOW; else if (errno == PGTYPES_NUM_UNDERFLOW) return ECPG_INFORMIX_NUM_UNDERFLOW; else if (errno != 0) return -1; else return 0;}intdeccmp(decimal *arg1, decimal *arg2){ return (deccall2(arg1, arg2, PGTYPESnumeric_cmp));}voiddeccopy(decimal *src, decimal *target){ memcpy(target, src, sizeof(decimal));}static char *ecpg_strndup(const char *str, size_t len){ int real_len = strlen(str); int use_len = (real_len > len) ? len : real_len; char *new = malloc(use_len + 1); if (new) { memcpy(new, str, use_len); new[use_len] = '\0'; } else errno = ENOMEM; return new;}intdeccvasc(char *cp, int len, decimal *np){ char *str; int ret = 0; numeric *result; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CSTRINGTYPE, cp)) return 0; str = ecpg_strndup(cp, len);/* decimal_in always converts the complete * string */ if (!str) ret = ECPG_INFORMIX_NUM_UNDERFLOW; else { errno = 0; result = PGTYPESnumeric_from_asc(str, NULL); if (!result) { switch (errno) { case PGTYPES_NUM_OVERFLOW: ret = ECPG_INFORMIX_NUM_OVERFLOW; break; case PGTYPES_NUM_BAD_NUMERIC: ret = ECPG_INFORMIX_BAD_NUMERIC; break; default: ret = ECPG_INFORMIX_BAD_EXPONENT; break; } } else { int i = PGTYPESnumeric_to_decimal(result, np); free(result); if (i != 0) ret = ECPG_INFORMIX_NUM_OVERFLOW; } } free(str); return ret;}intdeccvdbl(double dbl, decimal *np){ numeric *nres; int result = 1; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CDOUBLETYPE, (char *) &dbl)) return 0; nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; result = PGTYPESnumeric_from_double(dbl, nres); if (result == 0) result = PGTYPESnumeric_to_decimal(nres, np); PGTYPESnumeric_free(nres); return (result);}intdeccvint(int in, decimal *np){ numeric *nres; int result = 1; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CINTTYPE, (char *) &in)) return 0; nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; result = PGTYPESnumeric_from_int(in, nres); if (result == 0) result = PGTYPESnumeric_to_decimal(nres, np); PGTYPESnumeric_free(nres); return (result);}intdeccvlong(long lng, decimal *np){ numeric *nres; int result = 1; rsetnull(CDECIMALTYPE, (char *) np); if (risnull(CLONGTYPE, (char *) &lng)) return 0; nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; result = PGTYPESnumeric_from_long(lng, nres); if (result == 0) result = PGTYPESnumeric_to_decimal(nres, np); PGTYPESnumeric_free(nres); return (result);}intdecdiv(decimal *n1, decimal *n2, decimal *result){ int i; errno = 0; i = deccall3(n1, n2, result, PGTYPESnumeric_div); if (i != 0) switch (errno) { case PGTYPES_NUM_DIVIDE_ZERO: return ECPG_INFORMIX_DIVIDE_ZERO; break; case PGTYPES_NUM_OVERFLOW: return ECPG_INFORMIX_NUM_OVERFLOW; break; default: return ECPG_INFORMIX_NUM_UNDERFLOW; break; } return 0;}intdecmul(decimal *n1, decimal *n2, decimal *result){ int i; errno = 0; i = deccall3(n1, n2, result, PGTYPESnumeric_mul); if (i != 0) switch (errno) { case PGTYPES_NUM_OVERFLOW: return ECPG_INFORMIX_NUM_OVERFLOW; break; default: return ECPG_INFORMIX_NUM_UNDERFLOW; break; } return 0;}intdecsub(decimal *n1, decimal *n2, decimal *result){ int i; errno = 0; i = deccall3(n1, n2, result, PGTYPESnumeric_sub); if (i != 0) switch (errno) { case PGTYPES_NUM_OVERFLOW: return ECPG_INFORMIX_NUM_OVERFLOW; break; default: return ECPG_INFORMIX_NUM_UNDERFLOW; break; } return 0;}intdectoasc(decimal *np, char *cp, int len, int right){ char *str; numeric *nres; rsetnull(CSTRINGTYPE, (char *) cp); if (risnull(CDECIMALTYPE, (char *) np)) return 0; nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) { PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } if (right >= 0) str = PGTYPESnumeric_to_asc(nres, right); else str = PGTYPESnumeric_to_asc(nres, nres->dscale); PGTYPESnumeric_free(nres); if (!str) return -1; /* * TODO: have to take care of len here and create exponential notation if * necessary */ if ((int) (strlen(str) + 1) > len) { if (len > 1) { cp[0] = '*'; cp[1] = '\0'; } free(str); return -1; } else { strcpy(cp, str); free(str); return 0; }}intdectodbl(decimal *np, double *dblp){ int i; numeric *nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) { PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } i = PGTYPESnumeric_to_double(nres, dblp); PGTYPESnumeric_free(nres); return i;}intdectoint(decimal *np, int *ip){ int ret; numeric *nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) { PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } ret = PGTYPESnumeric_to_int(nres, ip); PGTYPESnumeric_free(nres); if (ret == PGTYPES_NUM_OVERFLOW) ret = ECPG_INFORMIX_NUM_OVERFLOW; return ret;}intdectolong(decimal *np, long *lngp){ int ret; numeric *nres = PGTYPESnumeric_new(); if (nres == NULL) return ECPG_INFORMIX_OUT_OF_MEMORY; if (PGTYPESnumeric_from_decimal(np, nres) != 0) { PGTYPESnumeric_free(nres); return ECPG_INFORMIX_OUT_OF_MEMORY; } ret = PGTYPESnumeric_to_long(nres, lngp); PGTYPESnumeric_free(nres); if (ret == PGTYPES_NUM_OVERFLOW) ret = ECPG_INFORMIX_NUM_OVERFLOW; return ret;}/* Now the date functions */intrdatestr(date d, char *str){ char *tmp = PGTYPESdate_to_asc(d); if (!tmp) return ECPG_INFORMIX_DATE_CONVERT; /* move to user allocated buffer */ strcpy(str, tmp); free(tmp); return 0;}/*** the input for this function is mmddyyyy and any non-numeric* character can be used as a separator**/intrstrdate(char *str, date * d){ return rdefmtdate(d, "mm/dd/yyyy", str);}voidrtoday(date * d){ PGTYPESdate_today(d); return;}intrjulmdy(date d, short mdy[3]){ int mdy_int[3]; PGTYPESdate_julmdy(d, mdy_int); mdy[0] = (short) mdy_int[0]; mdy[1] = (short) mdy_int[1]; mdy[2] = (short) mdy_int[2]; return 0;}intrdefmtdate(date * d, char *fmt, char *str)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -