mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
- Fixed truncate bug.
- Added patch by Christof Petig <christof.petig@wtal.de> to clean up ecpglib.
This commit is contained in:
parent
8ae8ddbb8e
commit
9f09e8362b
@ -1101,5 +1101,11 @@ Tue Sep 25 20:10:03 CEST 2001
|
|||||||
|
|
||||||
- Synced preproc.y with gram.y.
|
- Synced preproc.y with gram.y.
|
||||||
- Changed locale handling.
|
- Changed locale handling.
|
||||||
|
|
||||||
|
Mon Okt 1 13:49:40 CEST 2001
|
||||||
|
|
||||||
|
- Fixed truncate bug.
|
||||||
|
- Added patch by Christof Petig <christof.petig@wtal.de> to clean up
|
||||||
|
ecpglib.
|
||||||
- Set ecpg version to 2.9.0.
|
- Set ecpg version to 2.9.0.
|
||||||
- Set library version to 3.3.0.
|
- Set library version to 3.3.0.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.15 2001/09/19 14:09:32 meskes Exp $ */
|
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.16 2001/10/01 12:02:28 meskes Exp $ */
|
||||||
|
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#include "sqlca.h"
|
#include "sqlca.h"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||||
enum ECPGttype type, enum ECPGttype ind_type,
|
enum ECPGttype type, enum ECPGttype ind_type,
|
||||||
void *var, void *ind, long varcharsize, long offset,
|
void *var, void *ind, long varcharsize, long offset,
|
||||||
bool isarray)
|
bool isarray)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.25 2001/09/29 20:12:07 tgl Exp $ */
|
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.26 2001/10/01 12:02:28 meskes Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The aim is to get a simpler inteface to the database routines.
|
* The aim is to get a simpler inteface to the database routines.
|
||||||
@ -370,40 +370,107 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
|
|||||||
return isarray;
|
return isarray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ECPGstore_result(const PGresult *results, int act_field,
|
||||||
|
const struct statement * stmt, struct variable *var)
|
||||||
|
{ int isarray,
|
||||||
|
act_tuple,
|
||||||
|
ntuples = PQntuples(results);
|
||||||
|
bool status = true;
|
||||||
|
|
||||||
|
isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
|
||||||
|
|
||||||
|
if (!isarray)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if we don't have enough space, we cannot read
|
||||||
|
* all tuples
|
||||||
|
*/
|
||||||
|
if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
|
||||||
|
{
|
||||||
|
ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
|
||||||
|
stmt->lineno, ntuples, var->arrsize);
|
||||||
|
ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* since we read an array, the variable has to be
|
||||||
|
* an array too
|
||||||
|
*/
|
||||||
|
if (var->arrsize == 0)
|
||||||
|
{
|
||||||
|
ECPGlog("ECPGexecute line %d: variable is not an array\n");
|
||||||
|
ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* allocate memory for NULL pointers
|
||||||
|
*/
|
||||||
|
if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
switch (var->type)
|
||||||
|
{
|
||||||
|
case ECPGt_char:
|
||||||
|
case ECPGt_unsigned_char:
|
||||||
|
var->varcharsize = 0;
|
||||||
|
/* check strlen for each tuple */
|
||||||
|
for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
|
||||||
|
{
|
||||||
|
int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
|
||||||
|
|
||||||
|
if (len > var->varcharsize)
|
||||||
|
var->varcharsize = len;
|
||||||
|
}
|
||||||
|
var->offset *= var->varcharsize;
|
||||||
|
len = var->offset * ntuples;
|
||||||
|
break;
|
||||||
|
case ECPGt_varchar:
|
||||||
|
len = ntuples * (var->varcharsize + sizeof(int));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
len = var->offset * ntuples;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var->value = (void *) ecpg_alloc(len, stmt->lineno);
|
||||||
|
*((void **) var->pointer) = var->value;
|
||||||
|
add_mem(var->value, stmt->lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
|
||||||
|
{
|
||||||
|
if (!get_data(results, act_tuple, act_field, stmt->lineno,
|
||||||
|
var->type, var->ind_type, var->value,
|
||||||
|
var->ind_value, var->varcharsize, var->offset, isarray))
|
||||||
|
status = false;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ECPGexecute(struct statement * stmt)
|
ECPGstore_input(const struct statement * stmt, const struct variable *var,
|
||||||
|
const char **tobeinserted_p, bool *malloced_p)
|
||||||
{
|
{
|
||||||
bool status = false;
|
|
||||||
char *copiedquery;
|
|
||||||
PGresult *results;
|
|
||||||
PGnotify *notify;
|
|
||||||
struct variable *var;
|
|
||||||
|
|
||||||
copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now, if the type is one of the fill in types then we take the
|
|
||||||
* argument and enter that in the string at the first %s position.
|
|
||||||
* Then if there are any more fill in types we fill in at the next and
|
|
||||||
* so on.
|
|
||||||
*/
|
|
||||||
var = stmt->inlist;
|
|
||||||
while (var)
|
|
||||||
{
|
|
||||||
char *newcopy;
|
|
||||||
char *mallocedval = NULL;
|
char *mallocedval = NULL;
|
||||||
char *tobeinserted = NULL;
|
char *newcopy = NULL;
|
||||||
char *p;
|
|
||||||
char buff[20];
|
|
||||||
int hostvarl = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some special treatment is needed for records since we want
|
* Some special treatment is needed for records since we want
|
||||||
* their contents to arrive in a comma-separated list on insert (I
|
* their contents to arrive in a comma-separated list on insert (I
|
||||||
* think).
|
* think).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
buff[0] = '\0';
|
*malloced_p=false;
|
||||||
|
*tobeinserted_p="";
|
||||||
|
|
||||||
/* check for null value and set input buffer accordingly */
|
/* check for null value and set input buffer accordingly */
|
||||||
switch (var->ind_type)
|
switch (var->ind_type)
|
||||||
@ -411,30 +478,30 @@ ECPGexecute(struct statement * stmt)
|
|||||||
case ECPGt_short:
|
case ECPGt_short:
|
||||||
case ECPGt_unsigned_short:
|
case ECPGt_unsigned_short:
|
||||||
if (*(short *) var->ind_value < 0)
|
if (*(short *) var->ind_value < 0)
|
||||||
strcpy(buff, "null");
|
*tobeinserted_p="null";
|
||||||
break;
|
break;
|
||||||
case ECPGt_int:
|
case ECPGt_int:
|
||||||
case ECPGt_unsigned_int:
|
case ECPGt_unsigned_int:
|
||||||
if (*(int *) var->ind_value < 0)
|
if (*(int *) var->ind_value < 0)
|
||||||
strcpy(buff, "null");
|
*tobeinserted_p="null";
|
||||||
break;
|
break;
|
||||||
case ECPGt_long:
|
case ECPGt_long:
|
||||||
case ECPGt_unsigned_long:
|
case ECPGt_unsigned_long:
|
||||||
if (*(long *) var->ind_value < 0L)
|
if (*(long *) var->ind_value < 0L)
|
||||||
strcpy(buff, "null");
|
*tobeinserted_p="null";
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_LONG_LONG_INT_64
|
#ifdef HAVE_LONG_LONG_INT_64
|
||||||
case ECPGt_long_long:
|
case ECPGt_long_long:
|
||||||
case ECPGt_unsigned_long_long:
|
case ECPGt_unsigned_long_long:
|
||||||
if (*(long long int *) var->ind_value < (long long) 0)
|
if (*(long long int *) var->ind_value < (long long) 0)
|
||||||
strcpy(buff, "null");
|
*tobeinserted_p="null";
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*buff == '\0')
|
if (**tobeinserted_p == '\0')
|
||||||
{
|
{
|
||||||
switch (var->type)
|
switch (var->type)
|
||||||
{
|
{
|
||||||
@ -456,7 +523,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%hd", *((short *) var->value));
|
sprintf(mallocedval, "%hd", *((short *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_int:
|
case ECPGt_int:
|
||||||
@ -475,7 +543,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%d", *((int *) var->value));
|
sprintf(mallocedval, "%d", *((int *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_unsigned_short:
|
case ECPGt_unsigned_short:
|
||||||
@ -494,7 +563,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
|
sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_unsigned_int:
|
case ECPGt_unsigned_int:
|
||||||
@ -513,7 +583,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%u", *((unsigned int *) var->value));
|
sprintf(mallocedval, "%u", *((unsigned int *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_long:
|
case ECPGt_long:
|
||||||
@ -532,7 +603,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%ld", *((long *) var->value));
|
sprintf(mallocedval, "%ld", *((long *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_unsigned_long:
|
case ECPGt_unsigned_long:
|
||||||
@ -551,7 +623,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
|
sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_LONG_LONG_INT_64
|
#ifdef HAVE_LONG_LONG_INT_64
|
||||||
case ECPGt_long_long:
|
case ECPGt_long_long:
|
||||||
@ -570,7 +643,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%lld", *((long long *) var->value));
|
sprintf(mallocedval, "%lld", *((long long *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_unsigned_long_long:
|
case ECPGt_unsigned_long_long:
|
||||||
@ -589,7 +663,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%llu", *((unsigned long long *) var->value));
|
sprintf(mallocedval, "%llu", *((unsigned long long *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||||
case ECPGt_float:
|
case ECPGt_float:
|
||||||
@ -608,7 +683,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%.14g", *((float *) var->value));
|
sprintf(mallocedval, "%.14g", *((float *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_double:
|
case ECPGt_double:
|
||||||
@ -627,7 +703,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
else
|
else
|
||||||
sprintf(mallocedval, "%.14g", *((double *) var->value));
|
sprintf(mallocedval, "%.14g", *((double *) var->value));
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_bool:
|
case ECPGt_bool:
|
||||||
@ -664,7 +741,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
|
ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
|
||||||
}
|
}
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_char:
|
case ECPGt_char:
|
||||||
@ -685,7 +763,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
|
|
||||||
free(newcopy);
|
free(newcopy);
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ECPGt_char_variable:
|
case ECPGt_char_variable:
|
||||||
@ -698,7 +777,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
strncpy(mallocedval, (char *) var->value, slen);
|
strncpy(mallocedval, (char *) var->value, slen);
|
||||||
mallocedval[slen] = '\0';
|
mallocedval[slen] = '\0';
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ECPGt_varchar:
|
case ECPGt_varchar:
|
||||||
@ -718,7 +798,8 @@ ECPGexecute(struct statement * stmt)
|
|||||||
|
|
||||||
free(newcopy);
|
free(newcopy);
|
||||||
|
|
||||||
tobeinserted = mallocedval;
|
*tobeinserted_p = mallocedval;
|
||||||
|
*malloced_p = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -729,9 +810,38 @@ ECPGexecute(struct statement * stmt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
return true;
|
||||||
tobeinserted = buff;
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ECPGexecute(struct statement * stmt)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
char *copiedquery;
|
||||||
|
PGresult *results;
|
||||||
|
PGnotify *notify;
|
||||||
|
struct variable *var;
|
||||||
|
|
||||||
|
copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, if the type is one of the fill in types then we take the
|
||||||
|
* argument and enter that in the string at the first %s position.
|
||||||
|
* Then if there are any more fill in types we fill in at the next and
|
||||||
|
* so on.
|
||||||
|
*/
|
||||||
|
var = stmt->inlist;
|
||||||
|
while (var)
|
||||||
|
{
|
||||||
|
char *newcopy = NULL;
|
||||||
|
const char *tobeinserted = NULL;
|
||||||
|
char *p;
|
||||||
|
bool malloced=FALSE;
|
||||||
|
int hostvarl = 0;
|
||||||
|
|
||||||
|
if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
|
||||||
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now tobeinserted points to an area that is to be inserted at
|
* Now tobeinserted points to an area that is to be inserted at
|
||||||
* the first %s
|
* the first %s
|
||||||
@ -770,10 +880,10 @@ ECPGexecute(struct statement * stmt)
|
|||||||
* oldcopy and let the copiedquery get the var->value from the
|
* oldcopy and let the copiedquery get the var->value from the
|
||||||
* newcopy.
|
* newcopy.
|
||||||
*/
|
*/
|
||||||
if (mallocedval != NULL)
|
if (malloced)
|
||||||
{
|
{
|
||||||
free(mallocedval);
|
free((char*)tobeinserted);
|
||||||
mallocedval = NULL;
|
tobeinserted = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(copiedquery);
|
free(copiedquery);
|
||||||
@ -823,9 +933,7 @@ ECPGexecute(struct statement * stmt)
|
|||||||
{
|
{
|
||||||
int nfields,
|
int nfields,
|
||||||
ntuples,
|
ntuples,
|
||||||
act_tuple,
|
act_field;
|
||||||
act_field,
|
|
||||||
isarray;
|
|
||||||
|
|
||||||
case PGRES_TUPLES_OK:
|
case PGRES_TUPLES_OK:
|
||||||
nfields = PQnfields(results);
|
nfields = PQnfields(results);
|
||||||
@ -861,83 +969,9 @@ ECPGexecute(struct statement * stmt)
|
|||||||
ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
|
ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = ECPGstore_result(results, act_field, stmt, var);
|
||||||
|
|
||||||
isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
|
|
||||||
|
|
||||||
if (!isarray)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if we don't have enough space, we cannot read
|
|
||||||
* all tuples
|
|
||||||
*/
|
|
||||||
if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
|
|
||||||
{
|
|
||||||
ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
|
|
||||||
stmt->lineno, ntuples, var->arrsize);
|
|
||||||
ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
|
|
||||||
status = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* since we read an array, the variable has to be
|
|
||||||
* an array too
|
|
||||||
*/
|
|
||||||
if (var->arrsize == 0)
|
|
||||||
{
|
|
||||||
ECPGlog("ECPGexecute line %d: variable is not an array\n");
|
|
||||||
ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
|
|
||||||
status = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* allocate memory for NULL pointers
|
|
||||||
*/
|
|
||||||
if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
switch (var->type)
|
|
||||||
{
|
|
||||||
case ECPGt_char:
|
|
||||||
case ECPGt_unsigned_char:
|
|
||||||
var->varcharsize = 0;
|
|
||||||
/* check strlen for each tuple */
|
|
||||||
for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
|
|
||||||
{
|
|
||||||
int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
|
|
||||||
|
|
||||||
if (len > var->varcharsize)
|
|
||||||
var->varcharsize = len;
|
|
||||||
}
|
|
||||||
var->offset *= var->varcharsize;
|
|
||||||
len = var->offset * ntuples;
|
|
||||||
break;
|
|
||||||
case ECPGt_varchar:
|
|
||||||
len = ntuples * (var->varcharsize + sizeof(int));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
len = var->offset * ntuples;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var->value = (void *) ecpg_alloc(len, stmt->lineno);
|
|
||||||
*((void **) var->pointer) = var->value;
|
|
||||||
add_mem(var->value, stmt->lineno);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
|
|
||||||
{
|
|
||||||
if (!get_data(results, act_tuple, act_field, stmt->lineno,
|
|
||||||
var->type, var->ind_type, var->value,
|
|
||||||
var->ind_value, var->varcharsize, var->offset, isarray))
|
|
||||||
status = false;
|
|
||||||
}
|
|
||||||
var = var->next;
|
var = var->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,26 +1040,23 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
struct statement *stmt;
|
struct statement *stmt;
|
||||||
struct connection *con = get_connection(connection_name);
|
struct connection *con = get_connection(connection_name);
|
||||||
bool status;
|
bool status = true;
|
||||||
char *oldlocale;
|
char *locale;
|
||||||
|
|
||||||
/* Make sure we do NOT honor the locale for numeric input/output */
|
/* Make sure we do NOT honor the locale for numeric input/output */
|
||||||
/* since the database wants the standard decimal point */
|
/* since the database wants the standard decimal point */
|
||||||
oldlocale = strdup(setlocale(LC_NUMERIC, NULL));
|
locale = setlocale(LC_NUMERIC, "C");
|
||||||
setlocale(LC_NUMERIC, "C");
|
|
||||||
|
|
||||||
if (!ecpg_init(con, connection_name, lineno))
|
if (!ecpg_init(con, connection_name, lineno))
|
||||||
{
|
{
|
||||||
setlocale(LC_NUMERIC, oldlocale);
|
setlocale(LC_NUMERIC, locale);
|
||||||
free(oldlocale);
|
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(args, query);
|
va_start(args, query);
|
||||||
if (create_statement(lineno, con, &stmt, query, args) == false)
|
if (create_statement(lineno, con, &stmt, query, args) == false)
|
||||||
{
|
{
|
||||||
setlocale(LC_NUMERIC, oldlocale);
|
setlocale(LC_NUMERIC, locale);
|
||||||
free(oldlocale);
|
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
@ -1036,8 +1067,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
|
|||||||
free_statement(stmt);
|
free_statement(stmt);
|
||||||
ECPGlog("ECPGdo: not connected to %s\n", con->name);
|
ECPGlog("ECPGdo: not connected to %s\n", con->name);
|
||||||
ECPGraise(lineno, ECPG_NOT_CONN, NULL);
|
ECPGraise(lineno, ECPG_NOT_CONN, NULL);
|
||||||
setlocale(LC_NUMERIC, oldlocale);
|
setlocale(LC_NUMERIC, locale);
|
||||||
free(oldlocale);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,9 +1075,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
|
|||||||
free_statement(stmt);
|
free_statement(stmt);
|
||||||
|
|
||||||
/* and reset locale value so our application is not affected */
|
/* and reset locale value so our application is not affected */
|
||||||
setlocale(LC_NUMERIC, oldlocale);
|
setlocale(LC_NUMERIC, locale);
|
||||||
free(oldlocale);
|
|
||||||
|
|
||||||
return (status);
|
return (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
/* Here are some methods used by the lib. */
|
/* Here are some methods used by the lib. */
|
||||||
/* Returns a pointer to a string containing a simple type name. */
|
/* Returns a pointer to a string containing a simple type name. */
|
||||||
void free_auto_mem(void);
|
void free_auto_mem(void);
|
||||||
bool get_data(PGresult *, int, int, int, enum ECPGttype type,
|
bool get_data(const PGresult *, int, int, int, enum ECPGttype type,
|
||||||
enum ECPGttype, void *, void *, long, long, bool);
|
enum ECPGttype, void *, void *, long, long, bool);
|
||||||
struct connection *get_connection(const char *);
|
struct connection *get_connection(const char *);
|
||||||
void init_sqlca(void);
|
void init_sqlca(void);
|
||||||
@ -14,6 +14,7 @@ char *ecpg_strdup(const char *, int);
|
|||||||
const char *ECPGtype_name(enum ECPGttype);
|
const char *ECPGtype_name(enum ECPGttype);
|
||||||
unsigned int ECPGDynamicType(Oid);
|
unsigned int ECPGDynamicType(Oid);
|
||||||
|
|
||||||
|
|
||||||
/* A generic varchar type. */
|
/* A generic varchar type. */
|
||||||
struct ECPGgeneric_varchar
|
struct ECPGgeneric_varchar
|
||||||
{
|
{
|
||||||
@ -63,3 +64,7 @@ struct descriptor
|
|||||||
|
|
||||||
PGresult **
|
PGresult **
|
||||||
ECPGdescriptor_lvalue(int line, const char *descriptor);
|
ECPGdescriptor_lvalue(int line, const char *descriptor);
|
||||||
|
|
||||||
|
bool
|
||||||
|
ECPGstore_result(const PGresult *results, int act_field,
|
||||||
|
const struct statement * stmt, struct variable *var);
|
||||||
|
@ -1552,7 +1552,7 @@ drop_type: TABLE { $$ = make_str("table"); }
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
TruncateStmt: TRUNCATE opt_table relation_name
|
TruncateStmt: TRUNCATE opt_table relation_name
|
||||||
{
|
{
|
||||||
$$ = cat2_str(make_str("drop table"), $3);
|
$$ = cat2_str(make_str("truncate table"), $3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user