Commit a4f25b6a authored by Michael Meskes's avatar Michael Meskes

Started working on a seperate pgtypes library. First test work. PLEASE test...

Started working on a seperate pgtypes library. First test work. PLEASE test compilation on iother systems.
parent 48dfa0d0
...@@ -1353,6 +1353,14 @@ Tue Feb 25 16:46:27 CET 2003 ...@@ -1353,6 +1353,14 @@ Tue Feb 25 16:46:27 CET 2003
- Allow SET CONNECTION to be followed by connection object without - Allow SET CONNECTION to be followed by connection object without
leading "TO" or "=". leading "TO" or "=".
- Allow whenever statement to list function without parameters. - Allow whenever statement to list function without parameters.
Sun Mar 16 11:28:01 CET 2003
- Started with a pgtypes library.
- Renamed lib directory to ecpglib.
- Added numerical functions to library and preprocessor.
- Set ecpg version to 2.12.0. - Set ecpg version to 2.12.0.
- Set library to 3.4.2. - Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0
...@@ -4,11 +4,13 @@ include $(top_builddir)/src/Makefile.global ...@@ -4,11 +4,13 @@ include $(top_builddir)/src/Makefile.global
all install installdirs uninstall dep depend distprep: all install installdirs uninstall dep depend distprep:
$(MAKE) -C include $@ $(MAKE) -C include $@
$(MAKE) -C lib $@ $(MAKE) -C ecpglib $@
$(MAKE) -C pgtypeslib $@
$(MAKE) -C preproc $@ $(MAKE) -C preproc $@
clean distclean maintainer-clean: clean distclean maintainer-clean:
-$(MAKE) -C include $@ -$(MAKE) -C include $@
-$(MAKE) -C lib $@ -$(MAKE) -C ecpglib $@
-$(MAKE) -C pgtypeslib $@
-$(MAKE) -C preproc $@ -$(MAKE) -C preproc $@
-$(MAKE) -C test clean -$(MAKE) -C test clean
#-------------------------------------------------------------------------
#
# Makefile for ecpg library
#
# Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/Makefile,v 1.1 2003/03/16 10:42:53 meskes Exp $
#
#-------------------------------------------------------------------------
subdir = src/interfaces/ecpg/ecpglib
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
NAME= ecpg
SO_MAJOR_VERSION= 3
SO_MINOR_VERSION= 4.2
override CPPFLAGS := -g -I$(top_srcdir)/src/interfaces/ecpg/include -I$(libpq_srcdir) $(CPPFLAGS)
OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
connect.o misc.o
SHLIB_LINK= $(libpq)
all: all-lib
# Shared library stuff
include $(top_srcdir)/src/Makefile.shlib
install: all installdirs install-lib
installdirs:
$(mkinstalldirs) $(DESTDIR)$(libdir)
uninstall: uninstall-lib
clean distclean maintainer-clean: clean-lib
rm -f $(OBJS)
depend dep:
$(CC) -MM $(CFLAGS) *.c >depend
ifeq (depend,$(wildcard depend))
include depend
endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */
#include "postgres_fe.h"
#include <stdio.h>
#include "ecpgerrno.h"
#include "ecpgtype.h"
#include "ecpglib.h"
#include "extern.h"
#include "sqlca.h"
/* This should hold the back-end error message from
* the last back-end operation. */
static char *ECPGerr;
void
ECPGraise(int line, int code, const char *str)
{
sqlca.sqlcode = code;
switch (code)
{
case ECPG_NOT_FOUND:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"No data found in line %d.", line);
break;
case ECPG_OUT_OF_MEMORY:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Out of memory in line %d.", line);
break;
case ECPG_UNSUPPORTED:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Unsupported type %s in line %d.", str, line);
break;
case ECPG_TOO_MANY_ARGUMENTS:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Too many arguments in line %d.", line);
break;
case ECPG_TOO_FEW_ARGUMENTS:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Too few arguments in line %d.", line);
break;
case ECPG_INT_FORMAT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Not correctly formatted int type: %s line %d.", str, line);
break;
case ECPG_UINT_FORMAT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Not correctly formatted unsigned type: %s in line %d.", str, line);
break;
case ECPG_FLOAT_FORMAT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Not correctly formatted floating-point type: %s in line %d.", str, line);
break;
case ECPG_CONVERT_BOOL:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Unable to convert %s to bool on line %d.", str, line);
break;
case ECPG_EMPTY:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Empty query in line %d.", line);
break;
case ECPG_MISSING_INDICATOR:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"NULL value without indicator in line %d.", line);
break;
case ECPG_NO_ARRAY:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Variable is not an array in line %d.", line);
break;
case ECPG_DATA_NOT_ARRAY:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Data read from backend is not an array in line %d.", line);
break;
case ECPG_ARRAY_INSERT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Trying to insert an array of variables in line %d.", line);
break;
case ECPG_NO_CONN:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"No such connection %s in line %d.", str, line);
break;
case ECPG_NOT_CONN:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Not connected to '%s' in line %d.", str, line);
break;
case ECPG_INVALID_STMT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Invalid statement name %s in line %d.", str, line);
break;
case ECPG_UNKNOWN_DESCRIPTOR:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Descriptor %s not found in line %d.", str, line);
break;
case ECPG_INVALID_DESCRIPTOR_INDEX:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Descriptor index out of range in line %d.", line);
break;
case ECPG_UNKNOWN_DESCRIPTOR_ITEM:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Unknown descriptor item %s in line %d.", str, line);
break;
case ECPG_VAR_NOT_NUMERIC:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Variable is not a numeric type in line %d.", line);
break;
case ECPG_VAR_NOT_CHAR:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Variable is not a character type in line %d.", line);
break;
case ECPG_PGSQL:
{
int slen = strlen(str);
/* strip trailing newline */
if (slen > 0 && str[slen - 1] == '\n')
slen--;
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"'%.*s' in line %d.", slen, str, line);
break;
}
case ECPG_TRANS:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Error in transaction processing in line %d.", line);
break;
case ECPG_CONNECT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Could not connect to database %s in line %d.", str, line);
break;
default:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"SQL error #%d in line %d.", code, line);
break;
}
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
ECPGlog("raising sqlcode %d in line %d, '%s'.\n", code, line, sqlca.sqlerrm.sqlerrmc);
/* free all memory we have allocated for the user */
ECPGfree_auto_mem();
}
/* Set the error message string from the backend */
void
set_backend_err(const char *err, int lineno)
{
if (ECPGerr)
ECPGfree(ECPGerr);
if (!err)
{
ECPGerr = NULL;
return;
}
ECPGerr = ECPGstrdup(err, lineno);
}
/* Retrieve the error message from the backend. */
char *
ECPGerrmsg(void)
{
return ECPGerr;
}
/* print out an error message */
void
sqlprint(void)
{
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
fprintf(stderr, "sql error %s\n", sqlca.sqlerrm.sqlerrmc);
}
This diff is collapsed.
#ifndef _ECPG_LIB_EXTERN_H
#define _ECPG_LIB_EXTERN_H
#include "postgres_fe.h"
#include "libpq-fe.h"
/* Here are some methods used by the lib. */
/* Stores the backend error message for client access */
void set_backend_err(const char *err, int lineon);
/* Store and retrieve the backend error message for client access */
void set_backend_err(const char *err, int lineon);
char *ECPGerrmsg(void);
/* Returns a pointer to a string containing a simple type name. */
void ECPGadd_mem(void *ptr, int lineno);
bool ECPGget_data(const PGresult *, int, int, int, enum ECPGttype type,
enum ECPGttype, char *, char *, long, long, long, bool);
struct connection *ECPGget_connection(const char *);
void ECPGinit_sqlca(void);
char *ECPGalloc(long, int);
char *ECPGrealloc(void *, long, int);
void ECPGfree(void *);
bool ECPGinit(const struct connection *, const char *, const int);
char *ECPGstrdup(const char *, int);
const char *ECPGtype_name(enum ECPGttype);
unsigned int ECPGDynamicType(Oid);
void ECPGfree_auto_mem(void);
void ECPGclear_auto_mem(void);
/* A generic varchar type. */
struct ECPGgeneric_varchar
{
int len;
char arr[1];
};
/*
* type information cache
*/
struct ECPGtype_information_cache
{
struct ECPGtype_information_cache *next;
int oid;
bool isarray;
};
/* structure to store one statement */
struct statement
{
int lineno;
char *command;
struct connection *connection;
struct variable *inlist;
struct variable *outlist;
};
/* structure to store connections */
struct connection
{
char *name;
PGconn *connection;
bool committed;
int autocommit;
struct ECPGtype_information_cache *cache_head;
struct connection *next;
};
/* structure to store descriptors */
struct descriptor
{
char *name;
PGresult *result;
struct descriptor *next;
};
struct variable
{
enum ECPGttype type;
void *value;
void *pointer;
long varcharsize;
long arrsize;
long offset;
enum ECPGttype ind_type;
void *ind_value;
void *ind_pointer;
long ind_varcharsize;
long ind_arrsize;
long ind_offset;
struct variable *next;
};
PGresult **
ECPGdescriptor_lvalue(int line, const char *descriptor);
bool ECPGstore_result(const PGresult *results, int act_field,
const struct statement * stmt, struct variable * var);
#endif /* _ECPG_LIB_EXTERN_H */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */
#include "postgres_fe.h"
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "extern.h"
void
ECPGfree(void *ptr)
{
free(ptr);
}
char *
ECPGalloc(long size, int lineno)
{
char *new = (char *) calloc(1L, size);
if (!new)
{
ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
return NULL;
}
memset(new, '\0', size);
return (new);
}
char *
ECPGrealloc(void *ptr, long size, int lineno)
{
char *new = (char *) realloc(ptr, size);
if (!new)
{
ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
return NULL;
}
return (new);
}
char *
ECPGstrdup(const char *string, int lineno)
{
char *new = strdup(string);
if (!new)
{
ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
return NULL;
}
return (new);
}
/* keep a list of memory we allocated for the user */
static struct auto_mem
{
void *pointer;
struct auto_mem *next;
} *auto_allocs = NULL;
void
ECPGadd_mem(void *ptr, int lineno)
{
struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
am->pointer = ptr;
am->next = auto_allocs;
auto_allocs = am;
}
void
ECPGfree_auto_mem(void)
{
struct auto_mem *am;
/* free all memory we have allocated for the user */
for (am = auto_allocs; am;)
{
struct auto_mem *act = am;
am = am->next;
ECPGfree(act->pointer);
ECPGfree(act);
}
auto_allocs = NULL;
}
void
ECPGclear_auto_mem(void)
{
struct auto_mem *am;
/* free just our own structure */
for (am = auto_allocs; am;)
{
struct auto_mem *act = am;
am = am->next;
ECPGfree(act);
}
auto_allocs = NULL;
}
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */
#include "postgres_fe.h"
#include <unistd.h>
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "extern.h"
#include "sqlca.h"
static struct sqlca sqlca_init =
{
{
'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
},
sizeof(struct sqlca),
0,
{
0,
{
0
}
},
{
'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
},
{
0, 0, 0, 0, 0, 0
},
{
0, 0, 0, 0, 0, 0, 0, 0
},
{
0, 0, 0, 0, 0, 0, 0, 0
}
};
static int simple_debug = 0;
static FILE *debugstream = NULL;
void
ECPGinit_sqlca(void)
{
memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca));
}
bool
ECPGinit(const struct connection * con, const char *connection_name, const int lineno)
{
ECPGinit_sqlca();
if (con == NULL)
{
ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL");
return (false);
}
return (true);
}
bool
ECPGstatus(int lineno, const char *connection_name)
{
struct connection *con = ECPGget_connection(connection_name);
if (!ECPGinit(con, connection_name, lineno))
return (false);
/* are we connected? */
if (con->connection == NULL)
{
ECPGraise(lineno, ECPG_NOT_CONN, con->name);
return false;
}
return (true);
}
bool
ECPGtrans(int lineno, const char *connection_name, const char *transaction)
{
PGresult *res;
struct connection *con = ECPGget_connection(connection_name);
if (!ECPGinit(con, connection_name, lineno))
return (false);
ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name);
/* if we have no connection we just simulate the command */
if (con && con->connection)
{
/*
* if we are not in autocommit mode, already have committed the
* transaction and get another commit, just ignore it
*/
if (!con->committed || con->autocommit)
{
if ((res = PQexec(con->connection, transaction)) == NULL)
{
ECPGraise(lineno, ECPG_TRANS, NULL);
return FALSE;
}
PQclear(res);
}
}
if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
{
con->committed = true;
/* deallocate all prepared statements */
if (!ECPGdeallocate_all(lineno))
return false;
}
return true;
}
void
ECPGdebug(int n, FILE *dbgs)
{
simple_debug = n;
debugstream = dbgs;
ECPGlog("ECPGdebug: set to %d\n", simple_debug);
}
void
ECPGlog(const char *format,...)
{
va_list ap;
if (simple_debug)
{
char *f = (char *) malloc(strlen(format) + 100);
if (!f)
return;
sprintf(f, "[%d]: %s", (int) getpid(), format);
va_start(ap, format);
vfprintf(debugstream, f, ap);
va_end(ap);
ECPGfree(f);
}
}
/*-------------------------------------------------------------------------
*
* pg_type.h
* definition of the system "type" relation (pg_type)
* along with the relation's initial contents.
*
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_type.h,v 1.1 2003/03/16 10:42:53 meskes Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
* information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
#ifndef PG_TYPE_H
#define PG_TYPE_H
/* ----------------
* initial contents of pg_type
* ----------------
*/
/* keep the following ordered by OID so that later changes can be made easier*/
/* OIDS 1 - 99 */
#define BOOLOID 16
#define BYTEAOID 17
#define CHAROID 18
#define NAMEOID 19
#define INT8OID 20
#define INT2OID 21
#define INT2VECTOROID 22
#define INT4OID 23
#define REGPROCOID 24
#define TEXTOID 25
#define OIDOID 26
#define TIDOID 27
#define XIDOID 28
#define CIDOID 29
#define OIDVECTOROID 30
#define POINTOID 600
#define LSEGOID 601
#define PATHOID 602
#define BOXOID 603
#define POLYGONOID 604
#define LINEOID 628
#define FLOAT4OID 700
#define FLOAT8OID 701
#define ABSTIMEOID 702
#define RELTIMEOID 703
#define TINTERVALOID 704
#define UNKNOWNOID 705
#define CIRCLEOID 718
#define CASHOID 790
#define INETOID 869
#define CIDROID 650
#define BPCHAROID 1042
#define VARCHAROID 1043
#define DATEOID 1082
#define TIMEOID 1083
#define TIMESTAMPOID 1114
#define TIMESTAMPTZOID 1184
#define INTERVALOID 1186
#define TIMETZOID 1266
#define ZPBITOID 1560
#define VARBITOID 1562
#define NUMERICOID 1700
#endif /* PG_TYPE_H */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */
#include "postgres_fe.h"
#include <ctype.h>
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "extern.h"
#include "sqlca.h"
static struct prepared_statement
{
char *name;
struct statement *stmt;
struct prepared_statement *next;
} *prep_stmts = NULL;
static bool
isvarchar(unsigned char c)
{
if (isalnum(c))
return true;
if (c == '_' || c == '>' || c == '-' || c == '.')
return true;
if (c >= 128)
return true;
return (false);
}
static void
replace_variables(char *text)
{
char *ptr = text;
bool string = false;
for (; *ptr != '\0'; ptr++)
{
if (*ptr == '\'')
string = string ? false : true;
if (!string && *ptr == ':')
{
*ptr = '?';
for (++ptr; *ptr && isvarchar(*ptr); ptr++)
*ptr = ' ';
}
}
}
/* handle the EXEC SQL PREPARE statement */
bool
ECPGprepare(int lineno, char *name, char *variable)
{
struct statement *stmt;
struct prepared_statement *this;
/* check if we already have prepared this statement */
for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
if (this)
{
bool b = ECPGdeallocate(lineno, name);
if (!b)
return false;
}
this = (struct prepared_statement *) ECPGalloc(sizeof(struct prepared_statement), lineno);
if (!this)
return false;
stmt = (struct statement *) ECPGalloc(sizeof(struct statement), lineno);
if (!stmt)
{
ECPGfree(this);
return false;
}
/* create statement */
stmt->lineno = lineno;
stmt->connection = NULL;
stmt->command = ECPGstrdup(variable, lineno);
stmt->inlist = stmt->outlist = NULL;
/* if we have C variables in our statment replace them with '?' */
replace_variables(stmt->command);
/* add prepared statement to our list */
this->name = ECPGstrdup(name, lineno);
this->stmt = stmt;
if (prep_stmts == NULL)
this->next = NULL;
else
this->next = prep_stmts;
prep_stmts = this;
return true;
}
/* handle the EXEC SQL DEALLOCATE PREPARE statement */
bool
ECPGdeallocate(int lineno, char *name)
{
struct prepared_statement *this,
*prev;
/* check if we really have prepared this statement */
for (this = prep_stmts, prev = NULL; this != NULL && strcmp(this->name, name) != 0; prev = this, this = this->next);
if (this)
{
/* okay, free all the resources */
ECPGfree(this->name);
ECPGfree(this->stmt->command);
ECPGfree(this->stmt);
if (prev != NULL)
prev->next = this->next;
else
prep_stmts = this->next;
ECPGfree(this);
return true;
}
ECPGraise(lineno, ECPG_INVALID_STMT, name);
return false;
}
bool
ECPGdeallocate_all(int lineno)
{
/* deallocate all prepared statements */
while (prep_stmts != NULL)
{
bool b = ECPGdeallocate(lineno, prep_stmts->name);
if (!b)
return false;
}
return true;
}
/* return the prepared statement */
char *
ECPGprepared_statement(char *name)
{
struct prepared_statement *this;
for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
return (this) ? this->stmt->command : NULL;
}
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/typename.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */
#include "postgres_fe.h"
#include <stdlib.h>
#include "ecpgtype.h"
#include "ecpglib.h"
#include "extern.h"
#include "sql3types.h"
#include "pg_type.h"
/*
* This function is used to generate the correct type names.
*/
const char *
ECPGtype_name(enum ECPGttype typ)
{
switch (typ)
{
case ECPGt_char:
return "char";
case ECPGt_unsigned_char:
return "unsigned char";
case ECPGt_short:
return "short";
case ECPGt_unsigned_short:
return "unsigned short";
case ECPGt_int:
return "int";
case ECPGt_unsigned_int:
return "unsigned int";
case ECPGt_long:
return "long";
case ECPGt_unsigned_long:
return "unsigned long";
case ECPGt_long_long:
return "long long";
case ECPGt_unsigned_long_long:
return "unsigned long long";
case ECPGt_float:
return "float";
case ECPGt_double:
return "double";
case ECPGt_bool:
return "bool";
case ECPGt_varchar:
return "varchar";
case ECPGt_char_variable:
return "char";
case ECPGt_numeric:
return "numeric";
default:
abort();
}
return NULL;
}
unsigned int
ECPGDynamicType(Oid type)
{
switch (type)
{
case BOOLOID:
return SQL3_BOOLEAN; /* bool */
case INT2OID:
return SQL3_SMALLINT; /* int2 */
case INT4OID:
return SQL3_INTEGER; /* int4 */
case TEXTOID:
return SQL3_CHARACTER; /* text */
case FLOAT4OID:
return SQL3_REAL; /* float4 */
case FLOAT8OID:
return SQL3_DOUBLE_PRECISION; /* float8 */
case BPCHAROID:
return SQL3_CHARACTER; /* bpchar */
case VARCHAROID:
return SQL3_CHARACTER_VARYING; /* varchar */
case DATEOID:
return SQL3_DATE_TIME_TIMESTAMP; /* date */
case TIMEOID:
return SQL3_DATE_TIME_TIMESTAMP; /* time */
case TIMESTAMPOID:
return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
case NUMERICOID:
return SQL3_NUMERIC; /* numeric */
default:
return -type;
}
}
...@@ -5,7 +5,7 @@ include $(top_builddir)/src/Makefile.global ...@@ -5,7 +5,7 @@ include $(top_builddir)/src/Makefile.global
install: all installdirs install-headers install: all installdirs install-headers
.PHONY: install-headers .PHONY: install-headers
ecpg_headers = ecpgerrno.h ecpglib.h ecpgtype.h sqlca.h sql3types.h ecpg_informix.h ecpg_headers = ecpgerrno.h ecpglib.h ecpgtype.h sqlca.h sql3types.h ecpg_informix.h pgtypes_error.h pgtypes_numeric.h
install-headers: $(ecpg_headers) install-headers: $(ecpg_headers)
for i in $^; do $(INSTALL_DATA) $$i $(DESTDIR)$(includedir); done for i in $^; do $(INSTALL_DATA) $$i $(DESTDIR)$(includedir); done
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* that is registered and that has nothing whatsoever to do with the storage * that is registered and that has nothing whatsoever to do with the storage
* class. * class.
* *
* Simle types * Simple types
* integers: char, short, int, long (signed and unsigned) * integers: char, short, int, long (signed and unsigned)
* floats: float, double * floats: float, double
* *
...@@ -51,7 +51,8 @@ enum ECPGttype ...@@ -51,7 +51,8 @@ enum ECPGttype
ECPGt_EORT, /* End of result types. */ ECPGt_EORT, /* End of result types. */
ECPGt_NO_INDICATOR, /* no indicator */ ECPGt_NO_INDICATOR, /* no indicator */
ECPGt_long_long, ECPGt_unsigned_long_long, ECPGt_long_long, ECPGt_unsigned_long_long,
ECPGt_descriptor /* sql descriptor, no C variable */ ECPGt_descriptor, /* sql descriptor, no C variable */
ECPGt_numeric
}; };
/* descriptor items */ /* descriptor items */
...@@ -76,7 +77,7 @@ enum ECPGdtype ...@@ -76,7 +77,7 @@ enum ECPGdtype
ECPGd_cardinality ECPGd_cardinality
}; };
#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_varchar2) || ((type)>=ECPGt_long_long && (type) <= ECPGt_unsigned_long_long)) #define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_varchar2) || ((type)>=ECPGt_long_long && (type) <= ECPGt_unsigned_long_long) || (type) >= ECPGt_numeric)
#ifdef __cplusplus #ifdef __cplusplus
} }
......
#-------------------------------------------------------------------------
#
# Makefile for ecpg library
#
# Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/Makefile,v 1.1 2003/03/16 10:42:54 meskes Exp $
#
#-------------------------------------------------------------------------
subdir = src/interfaces/ecpg/pgtypeslib
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
NAME= pgtypes
SO_MAJOR_VERSION= 1
SO_MINOR_VERSION= 0.0
override CPPFLAGS := -g -I$(top_srcdir)/src/interfaces/ecpg/include -I$(top_srcdir)/src/include/utils $(CPPFLAGS)
OBJS= numeric.o
all: all-lib
# Shared library stuff
include $(top_srcdir)/src/Makefile.shlib
install: all installdirs install-lib
installdirs:
$(mkinstalldirs) $(DESTDIR)$(libdir)
uninstall: uninstall-lib
clean distclean maintainer-clean: clean-lib
rm -f $(OBJS)
depend dep:
$(CC) -MM $(CFLAGS) *.c >depend
ifeq (depend,$(wildcard depend))
include depend
endif
This diff is collapsed.
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.61 2003/03/10 22:28:21 tgl Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.62 2003/03/16 10:42:54 meskes Exp $ */
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */ /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */ /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
...@@ -313,7 +313,7 @@ main(int argc, char *const argv[]) ...@@ -313,7 +313,7 @@ main(int argc, char *const argv[])
lex_init(); lex_init();
/* we need several includes */ /* we need several includes */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These four include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n#include <ecpgerrno.h>\n#include <sqlca.h>\n#line 1 \"%s\"\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, input_filename); fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These four include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n#include <ecpgerrno.h>\n#include <sqlca.h>\n#include <pgtypes_numeric.h>\n#line 1 \"%s\"\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, input_filename);
/* add some compatibility headers */ /* add some compatibility headers */
if (compat == ECPG_COMPAT_INFORMIX) if (compat == ECPG_COMPAT_INFORMIX)
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.211 2003/02/25 15:58:03 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.212 2003/03/16 10:42:54 meskes Exp $ */
/* Copyright comment */ /* Copyright comment */
%{ %{
...@@ -211,7 +211,7 @@ make_name(void) ...@@ -211,7 +211,7 @@ make_name(void)
KEY KEY
LANCOMPILER LANGUAGE LAST LEADING LEFT LEVEL LIKE LIMIT LISTEN LANCOMPILER LANGUAGE LEADING LEFT LEVEL LIKE LIMIT LISTEN
LOAD LOCAL LOCATION LOCK_P LOAD LOCAL LOCATION LOCK_P
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
...@@ -303,7 +303,7 @@ make_name(void) ...@@ -303,7 +303,7 @@ make_name(void)
%type <str> Typename SimpleTypename Numeric opt_float opt_numeric %type <str> Typename SimpleTypename Numeric opt_float opt_numeric
%type <str> opt_decimal Character character opt_varying opt_charset %type <str> opt_decimal Character character opt_varying opt_charset
%type <str> opt_collate opt_timezone opt_interval table_ref %type <str> opt_collate opt_timezone opt_interval table_ref
%type <str> row_descriptor ConstDatetime AlterDomainStmt %type <str> row_descriptor ConstDatetime AlterDomainStmt
%type <str> SelectStmt into_clause OptTemp ConstraintAttributeSpec %type <str> SelectStmt into_clause OptTemp ConstraintAttributeSpec
%type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr %type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr
%type <str> sortby OptUseOp qualified_name_list name_list ColId_or_Sconst %type <str> sortby OptUseOp qualified_name_list name_list ColId_or_Sconst
...@@ -390,7 +390,7 @@ make_name(void) ...@@ -390,7 +390,7 @@ make_name(void)
%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol %type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
%type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration %type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
%type <str> reserved_keyword unreserved_keyword %type <str> reserved_keyword unreserved_keyword
%type <str> col_name_keyword func_name_keyword %type <str> col_name_keyword func_name_keyword precision opt_scale
%type <str> ECPGTypeName variablelist ECPGColLabelCommon %type <str> ECPGTypeName variablelist ECPGColLabelCommon
%type <descriptor> ECPGGetDescriptor %type <descriptor> ECPGGetDescriptor
...@@ -399,11 +399,11 @@ make_name(void) ...@@ -399,11 +399,11 @@ make_name(void)
%type <dtype_enum> descriptor_item desc_header_item %type <dtype_enum> descriptor_item desc_header_item
%type <type> type common_type single_vt_type %type <type> var_type common_type single_vt_type
%type <action> action %type <action> action
%type <index> opt_array_bounds opt_type_array_bounds %type <index> opt_array_bounds
%type <ival> Iresult %type <ival> Iresult
...@@ -4158,11 +4158,11 @@ single_var_declaration: storage_declaration ...@@ -4158,11 +4158,11 @@ single_var_declaration: storage_declaration
/* we do not need the string "varchar" for output */ /* we do not need the string "varchar" for output */
/* so replace it with an empty string */ /* so replace it with an empty string */
if ($2.type_enum == ECPGt_varchar) /* if ($2.type_enum == ECPGt_varchar)
{ {
free($2.type_str); free($2.type_str);
$2.type_str=EMPTY; $2.type_str=EMPTY;
} }*/
} }
variable_list ';' variable_list ';'
{ {
...@@ -4170,6 +4170,12 @@ single_var_declaration: storage_declaration ...@@ -4170,6 +4170,12 @@ single_var_declaration: storage_declaration
} }
; ;
precision: NumConst { $$ = $1; };
opt_scale: ',' NumConst { $$ = $2; }
| /* EMPTY */ { $$ = EMPTY; }
;
single_vt_type: common_type single_vt_type: common_type
| ECPGColLabelCommon | ECPGColLabelCommon
{ {
...@@ -4180,7 +4186,7 @@ single_vt_type: common_type ...@@ -4180,7 +4186,7 @@ single_vt_type: common_type
if (strcmp($1, "varchar") == 0) if (strcmp($1, "varchar") == 0)
{ {
$$.type_enum = ECPGt_varchar; $$.type_enum = ECPGt_varchar;
$$.type_str = make_str("varchar"); $$.type_str = EMPTY;
$$.type_dimension = -1; $$.type_dimension = -1;
$$.type_index = -1; $$.type_index = -1;
$$.type_sizeof = NULL; $$.type_sizeof = NULL;
...@@ -4201,6 +4207,22 @@ single_vt_type: common_type ...@@ -4201,6 +4207,22 @@ single_vt_type: common_type
$$.type_index = -1; $$.type_index = -1;
$$.type_sizeof = NULL; $$.type_sizeof = NULL;
} }
else if (strcmp($1, "numeric") == 0)
{
$$.type_enum = ECPGt_numeric;
$$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
$$.type_sizeof = NULL;
}
else if (strcmp($1, "decimal") == 0)
{
$$.type_enum = ECPGt_numeric;
$$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
$$.type_sizeof = NULL;
}
else else
{ {
/* this is for typedef'ed types */ /* this is for typedef'ed types */
...@@ -4214,6 +4236,17 @@ single_vt_type: common_type ...@@ -4214,6 +4236,17 @@ single_vt_type: common_type
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
} }
} }
| ECPGColLabelCommon '(' precision opt_scale ')'
{
if (strcmp($1, "numeric") != 0 && strcmp($1, "decimal") != 0)
mmerror(PARSE_ERROR, ET_ERROR, "Only numeric/decimal have precision/scale argument");
$$.type_enum = ECPGt_numeric;
$$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
$$.type_sizeof = NULL;
}
; ;
/* /*
...@@ -4253,7 +4286,7 @@ type_declaration: S_TYPEDEF ...@@ -4253,7 +4286,7 @@ type_declaration: S_TYPEDEF
/* an initializer specified */ /* an initializer specified */
initializer = 0; initializer = 0;
} }
type opt_pointer ECPGColLabel opt_type_array_bounds ';' var_type opt_pointer ECPGColLabel opt_array_bounds ';'
{ {
/* add entry to list */ /* add entry to list */
struct typedefs *ptr, *this; struct typedefs *ptr, *this;
...@@ -4310,7 +4343,7 @@ type_declaration: S_TYPEDEF ...@@ -4310,7 +4343,7 @@ type_declaration: S_TYPEDEF
}; };
var_declaration: storage_declaration var_declaration: storage_declaration
type var_type
{ {
actual_type[struct_level].type_enum = $2.type_enum; actual_type[struct_level].type_enum = $2.type_enum;
actual_type[struct_level].type_dimension = $2.type_dimension; actual_type[struct_level].type_dimension = $2.type_dimension;
...@@ -4319,11 +4352,11 @@ var_declaration: storage_declaration ...@@ -4319,11 +4352,11 @@ var_declaration: storage_declaration
/* we do not need the string "varchar" for output */ /* we do not need the string "varchar" for output */
/* so replace it with an empty string */ /* so replace it with an empty string */
if ($2.type_enum == ECPGt_varchar) /* if ($2.type_enum == ECPGt_varchar)
{ {
free($2.type_str); free($2.type_str);
$2.type_str=EMPTY; $2.type_str=EMPTY;
} }*/
} }
variable_list ';' variable_list ';'
{ {
...@@ -4384,7 +4417,7 @@ common_type: simple_type ...@@ -4384,7 +4417,7 @@ common_type: simple_type
} }
; ;
type: common_type var_type: common_type
| ECPGColLabel | ECPGColLabel
{ {
/* /*
...@@ -4394,7 +4427,7 @@ type: common_type ...@@ -4394,7 +4427,7 @@ type: common_type
if (strcmp($1, "varchar") == 0) if (strcmp($1, "varchar") == 0)
{ {
$$.type_enum = ECPGt_varchar; $$.type_enum = ECPGt_varchar;
$$.type_str = make_str("varchar"); $$.type_str = EMPTY; /*make_str("varchar");*/
$$.type_dimension = -1; $$.type_dimension = -1;
$$.type_index = -1; $$.type_index = -1;
$$.type_sizeof = NULL; $$.type_sizeof = NULL;
...@@ -4415,6 +4448,22 @@ type: common_type ...@@ -4415,6 +4448,22 @@ type: common_type
$$.type_index = -1; $$.type_index = -1;
$$.type_sizeof = NULL; $$.type_sizeof = NULL;
} }
else if (strcmp($1, "numeric") == 0)
{
$$.type_enum = ECPGt_numeric;
$$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
$$.type_sizeof = NULL;
}
else if (strcmp($1, "decimal") == 0)
{
$$.type_enum = ECPGt_numeric;
$$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
$$.type_sizeof = NULL;
}
else else
{ {
/* this is for typedef'ed types */ /* this is for typedef'ed types */
...@@ -4428,6 +4477,17 @@ type: common_type ...@@ -4428,6 +4477,17 @@ type: common_type
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
} }
} }
| ECPGColLabelCommon '(' precision opt_scale ')'
{
if (strcmp($1, "numeric") != 0 && strcmp($1, "decimal") != 0)
mmerror(PARSE_ERROR, ET_ERROR, "Only numeric/decimal have precision/scale argument");
$$.type_enum = ECPGt_numeric;
$$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
$$.type_sizeof = NULL;
}
; ;
enum_type: SQL_ENUM opt_symbol enum_definition enum_type: SQL_ENUM opt_symbol enum_definition
...@@ -4600,6 +4660,18 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer ...@@ -4600,6 +4660,18 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
$$ = cat_str(4, $1, mm_strdup($2), $3.str, $4); $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
break; break;
case ECPGt_numeric:
if (dimension < 0)
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
else
type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
if (dimension < 0)
$$ = cat_str(4, mm_strdup(actual_storage[struct_level]), make_str("NumericVar"), mm_strdup($2), $4);
else
$$ = cat_str(5, mm_strdup(actual_storage[struct_level]), make_str("NumericVar"), mm_strdup($2), mm_strdup(dim), $4);
break;
default: default:
if (dimension < 0) if (dimension < 0)
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1); type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
...@@ -4870,7 +4942,7 @@ ECPGTypedef: TYPE_P ...@@ -4870,7 +4942,7 @@ ECPGTypedef: TYPE_P
/* an initializer specified */ /* an initializer specified */
initializer = 0; initializer = 0;
} }
ColLabel IS type opt_type_array_bounds opt_reference ColLabel IS var_type opt_array_bounds opt_reference
{ {
/* add entry to list */ /* add entry to list */
struct typedefs *ptr, *this; struct typedefs *ptr, *this;
...@@ -4925,44 +4997,6 @@ ECPGTypedef: TYPE_P ...@@ -4925,44 +4997,6 @@ ECPGTypedef: TYPE_P
} }
; ;
opt_type_array_bounds: '[' ']' opt_type_array_bounds
{
$$.index1 = 0;
$$.index2 = $3.index1;
$$.str = cat2_str(make_str("[]"), $3.str);
}
| '(' ')' opt_type_array_bounds
{
$$.index1 = 0;
$$.index2 = $3.index1;
$$.str = cat2_str(make_str("[]"), $3.str);
}
| '[' Iresult ']' opt_type_array_bounds
{
char *txt = mm_alloc(20L);
sprintf (txt, "%d", $2);
$$.index1 = $2;
$$.index2 = $4.index1;
$$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
}
| '(' Iresult ')' opt_type_array_bounds
{
char *txt = mm_alloc(20L);
sprintf (txt, "%d", $2);
$$.index1 = $2;
$$.index2 = $4.index1;
$$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
}
| /* EMPTY */
{
$$.index1 = -1;
$$.index2 = -1;
$$.str= EMPTY;
}
;
opt_reference: SQL_REFERENCE { $$ = make_str("reference"); } opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
| /*EMPTY*/ { $$ = EMPTY; } | /*EMPTY*/ { $$ = EMPTY; }
; ;
...@@ -4976,7 +5010,7 @@ ECPGVar: SQL_VAR ...@@ -4976,7 +5010,7 @@ ECPGVar: SQL_VAR
/* an initializer specified */ /* an initializer specified */
initializer = 0; initializer = 0;
} }
ColLabel IS type opt_type_array_bounds opt_reference ColLabel IS var_type opt_array_bounds opt_reference
{ {
struct variable *p = find_variable($3); struct variable *p = find_variable($3);
int dimension = $6.index1; int dimension = $6.index1;
......
...@@ -169,6 +169,9 @@ get_type(enum ECPGttype type) ...@@ -169,6 +169,9 @@ get_type(enum ECPGttype type)
* quoted */ * quoted */
return ("ECPGt_char_variable"); return ("ECPGt_char_variable");
break; break;
case ECPGt_numeric:
return ("ECPGt_numeric");
break;
case ECPGt_descriptor: case ECPGt_descriptor:
return ("ECPGt_descriptor"); return ("ECPGt_descriptor");
break; break;
...@@ -319,6 +322,14 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, ...@@ -319,6 +322,14 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
sprintf(offset, "%ld*sizeof(char)", varcharsize == 0 ? 1 : varcharsize); sprintf(offset, "%ld*sizeof(char)", varcharsize == 0 ? 1 : varcharsize);
break; break;
case ECPGt_numeric:
/*
* we have to use a pointer here
*/
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
sprintf(offset, "sizeof(struct NumericVar)");
break;
default: default:
/* /*
......
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.33 2001/12/23 12:17:41 meskes Exp $ # $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.34 2003/03/16 10:42:54 meskes Exp $
subdir = src/interfaces/ecpg/test subdir = src/interfaces/ecpg/test
top_builddir = ../../../.. top_builddir = ../../../..
...@@ -8,12 +8,12 @@ override CPPFLAGS := -I$(srcdir)/../include $(CPPFLAGS) -g ...@@ -8,12 +8,12 @@ override CPPFLAGS := -I$(srcdir)/../include $(CPPFLAGS) -g
ECPG = ../preproc/ecpg -I$(srcdir)/../include ECPG = ../preproc/ecpg -I$(srcdir)/../include
TESTS = test1 test2 test3 test4 perftest dyntest dyntest2 test_notice test_code100 test_init testdynalloc TESTS = test1 test2 test3 test4 perftest dyntest dyntest2 test_notice test_code100 test_init testdynalloc num_test
all: $(TESTS) all: $(TESTS)
%: %.o %: %.o
$(CC) $(CFLAGS) $(LDFLAGS) -L../lib -L../../libpq $^ $(LIBS) -lecpg -lpq -o $@ $(CC) $(CFLAGS) $(LDFLAGS) -L../ecpglib -L ../pgtypeslib -L../../libpq $^ $(LIBS) -lpgtypes -lecpg -lpq -o $@
%.c: %.pgc %.c: %.pgc
$(ECPG) $< $(ECPG) $<
......
#include <stdio.h>
int
main()
{
char *text="error\n";
NumericVar *value1, *value2, *res;
exec sql begin declare section;
decimal(14,7) des = {0, 0, 0, 0, 0, NULL, NULL} ;
exec sql end declare section;
double d;
FILE *dbgs;
if ((dbgs = fopen("log", "w")) != NULL)
ECPGdebug(1, dbgs);
exec sql whenever sqlerror do sqlprint();
exec sql connect to mm;
exec sql create table test (text char(5), num decimal(14,7));
value1 = PGTYPESnew();
PGTYPESnumeric_iton(1407, value1);
text = PGTYPESnumeric_ntoa(value1);
printf("long = %s\n", text);
value1 = PGTYPESnumeric_aton("2369.7", -1);
value2 = PGTYPESnumeric_aton("10.0", -1);
res = PGTYPESnew();
decadd(value1, value2, res);
text = PGTYPESnumeric_ntoa(res);
printf("add = %s\n", text);
PGTYPESnumeric_sub(res, value2, res);
text = PGTYPESnumeric_ntoa(res);
printf("sub = %s\n", text);
PGTYPESnumeric_copy(res, &des);
exec sql insert into test (text, num) values ('test', :des);
value2 = PGTYPESnumeric_aton("2369.7", -1);
PGTYPESnumeric_mul(value1, value2, res);
exec sql select num into :des from test where text = 'test';
PGTYPESnumeric_mul(res, &des, res);
text = PGTYPESnumeric_ntoa(res);
printf("mul = %s\n", text);
value2 = PGTYPESnumeric_aton("10000", -1);
PGTYPESnumeric_div(res, value2, res);
text = PGTYPESnumeric_ntoa(res);
PGTYPESnumeric_ntod(res, &d);
printf("div = %s %e\n", text, d);
return (0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment