mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Standard pgindent run for 8.1.
This commit is contained in:
@ -15,7 +15,7 @@
|
||||
char *ECPGalloc(long, int);
|
||||
|
||||
static int
|
||||
deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
|
||||
deccall2(decimal * arg1, decimal * arg2, int (*ptr) (numeric *, numeric *))
|
||||
{
|
||||
numeric *a1,
|
||||
*a2;
|
||||
@ -53,7 +53,7 @@ deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
|
||||
}
|
||||
|
||||
static int
|
||||
deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *))
|
||||
deccall3(decimal * arg1, decimal * arg2, decimal * result, int (*ptr) (numeric *, numeric *, numeric *))
|
||||
{
|
||||
numeric *a1,
|
||||
*a2,
|
||||
@ -118,7 +118,7 @@ deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, n
|
||||
|
||||
/* we start with the numeric functions */
|
||||
int
|
||||
decadd(decimal *arg1, decimal *arg2, decimal *sum)
|
||||
decadd(decimal * arg1, decimal * arg2, decimal * sum)
|
||||
{
|
||||
deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
|
||||
|
||||
@ -131,13 +131,13 @@ decadd(decimal *arg1, decimal *arg2, decimal *sum)
|
||||
}
|
||||
|
||||
int
|
||||
deccmp(decimal *arg1, decimal *arg2)
|
||||
deccmp(decimal * arg1, decimal * arg2)
|
||||
{
|
||||
return (deccall2(arg1, arg2, PGTYPESnumeric_cmp));
|
||||
}
|
||||
|
||||
void
|
||||
deccopy(decimal *src, decimal *target)
|
||||
deccopy(decimal * src, decimal * target)
|
||||
{
|
||||
memcpy(target, src, sizeof(decimal));
|
||||
}
|
||||
@ -162,11 +162,10 @@ ecpg_strndup(const char *str, size_t len)
|
||||
}
|
||||
|
||||
int
|
||||
deccvasc(char *cp, int len, decimal *np)
|
||||
deccvasc(char *cp, int len, decimal * np)
|
||||
{
|
||||
char *str = ecpg_strndup(cp, len); /* decimal_in always
|
||||
* converts the complete
|
||||
* string */
|
||||
char *str = ecpg_strndup(cp, len); /* decimal_in always converts
|
||||
* the complete string */
|
||||
int ret = 0;
|
||||
numeric *result;
|
||||
|
||||
@ -208,7 +207,7 @@ deccvasc(char *cp, int len, decimal *np)
|
||||
}
|
||||
|
||||
int
|
||||
deccvdbl(double dbl, decimal *np)
|
||||
deccvdbl(double dbl, decimal * np)
|
||||
{
|
||||
numeric *nres = PGTYPESnumeric_new();
|
||||
int result = 1;
|
||||
@ -229,7 +228,7 @@ deccvdbl(double dbl, decimal *np)
|
||||
}
|
||||
|
||||
int
|
||||
deccvint(int in, decimal *np)
|
||||
deccvint(int in, decimal * np)
|
||||
{
|
||||
numeric *nres = PGTYPESnumeric_new();
|
||||
int result = 1;
|
||||
@ -250,7 +249,7 @@ deccvint(int in, decimal *np)
|
||||
}
|
||||
|
||||
int
|
||||
deccvlong(long lng, decimal *np)
|
||||
deccvlong(long lng, decimal * np)
|
||||
{
|
||||
numeric *nres = PGTYPESnumeric_new();
|
||||
int result = 1;
|
||||
@ -271,7 +270,7 @@ deccvlong(long lng, decimal *np)
|
||||
}
|
||||
|
||||
int
|
||||
decdiv(decimal *n1, decimal *n2, decimal *result)
|
||||
decdiv(decimal * n1, decimal * n2, decimal * result)
|
||||
{
|
||||
|
||||
int i;
|
||||
@ -296,7 +295,7 @@ decdiv(decimal *n1, decimal *n2, decimal *result)
|
||||
}
|
||||
|
||||
int
|
||||
decmul(decimal *n1, decimal *n2, decimal *result)
|
||||
decmul(decimal * n1, decimal * n2, decimal * result)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -317,7 +316,7 @@ decmul(decimal *n1, decimal *n2, decimal *result)
|
||||
}
|
||||
|
||||
int
|
||||
decsub(decimal *n1, decimal *n2, decimal *result)
|
||||
decsub(decimal * n1, decimal * n2, decimal * result)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -338,7 +337,7 @@ decsub(decimal *n1, decimal *n2, decimal *result)
|
||||
}
|
||||
|
||||
int
|
||||
dectoasc(decimal *np, char *cp, int len, int right)
|
||||
dectoasc(decimal * np, char *cp, int len, int right)
|
||||
{
|
||||
char *str;
|
||||
numeric *nres = PGTYPESnumeric_new();
|
||||
@ -373,7 +372,7 @@ dectoasc(decimal *np, char *cp, int len, int right)
|
||||
}
|
||||
|
||||
int
|
||||
dectodbl(decimal *np, double *dblp)
|
||||
dectodbl(decimal * np, double *dblp)
|
||||
{
|
||||
numeric *nres = PGTYPESnumeric_new();
|
||||
int i;
|
||||
@ -391,7 +390,7 @@ dectodbl(decimal *np, double *dblp)
|
||||
}
|
||||
|
||||
int
|
||||
dectoint(decimal *np, int *ip)
|
||||
dectoint(decimal * np, int *ip)
|
||||
{
|
||||
int ret;
|
||||
numeric *nres = PGTYPESnumeric_new();
|
||||
@ -411,7 +410,7 @@ dectoint(decimal *np, int *ip)
|
||||
}
|
||||
|
||||
int
|
||||
dectolong(decimal *np, long *lngp)
|
||||
dectolong(decimal * np, long *lngp)
|
||||
{
|
||||
int ret;
|
||||
numeric *nres = PGTYPESnumeric_new();;
|
||||
@ -453,7 +452,7 @@ rdatestr(date d, char *str)
|
||||
*
|
||||
*/
|
||||
int
|
||||
rstrdate(char *str, date *d)
|
||||
rstrdate(char *str, date * d)
|
||||
{
|
||||
date dat;
|
||||
char strbuf[10];
|
||||
@ -511,7 +510,7 @@ rstrdate(char *str, date *d)
|
||||
}
|
||||
|
||||
void
|
||||
rtoday(date *d)
|
||||
rtoday(date * d)
|
||||
{
|
||||
PGTYPESdate_today(d);
|
||||
return;
|
||||
@ -530,7 +529,7 @@ rjulmdy(date d, short mdy[3])
|
||||
}
|
||||
|
||||
int
|
||||
rdefmtdate(date *d, char *fmt, char *str)
|
||||
rdefmtdate(date * d, char *fmt, char *str)
|
||||
{
|
||||
/* TODO: take care of DBCENTURY environment variable */
|
||||
/* PGSQL functions allow all centuries */
|
||||
@ -567,7 +566,7 @@ rfmtdate(date d, char *fmt, char *str)
|
||||
}
|
||||
|
||||
int
|
||||
rmdyjul(short mdy[3], date *d)
|
||||
rmdyjul(short mdy[3], date * d)
|
||||
{
|
||||
int mdy_int[3];
|
||||
|
||||
@ -587,13 +586,13 @@ rdayofweek(date d)
|
||||
/* And the datetime stuff */
|
||||
|
||||
void
|
||||
dtcurrent(timestamp *ts)
|
||||
dtcurrent(timestamp * ts)
|
||||
{
|
||||
PGTYPEStimestamp_current(ts);
|
||||
}
|
||||
|
||||
int
|
||||
dtcvasc(char *str, timestamp *ts)
|
||||
dtcvasc(char *str, timestamp * ts)
|
||||
{
|
||||
timestamp ts_tmp;
|
||||
int i;
|
||||
@ -616,13 +615,13 @@ dtcvasc(char *str, timestamp *ts)
|
||||
}
|
||||
|
||||
int
|
||||
dtsub(timestamp *ts1, timestamp *ts2, interval *iv)
|
||||
dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
|
||||
{
|
||||
return PGTYPEStimestamp_sub(ts1, ts2, iv);
|
||||
}
|
||||
|
||||
int
|
||||
dttoasc(timestamp *ts, char *output)
|
||||
dttoasc(timestamp * ts, char *output)
|
||||
{
|
||||
char *asctime = PGTYPEStimestamp_to_asc(*ts);
|
||||
|
||||
@ -632,13 +631,13 @@ dttoasc(timestamp *ts, char *output)
|
||||
}
|
||||
|
||||
int
|
||||
dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr)
|
||||
dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
|
||||
{
|
||||
return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
|
||||
}
|
||||
|
||||
int
|
||||
intoasc(interval *i, char *str)
|
||||
intoasc(interval * i, char *str)
|
||||
{
|
||||
str = PGTYPESinterval_to_asc(i);
|
||||
|
||||
@ -963,7 +962,7 @@ rtypwidth(int sqltype, int sqllen)
|
||||
}
|
||||
|
||||
int
|
||||
dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue)
|
||||
dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
|
||||
{
|
||||
return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.25 2005/04/14 10:08:57 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.26 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
#define POSTGRES_ECPG_INTERNAL
|
||||
#include "postgres_fe.h"
|
||||
@ -16,7 +16,6 @@
|
||||
static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_key_t actual_connection_key;
|
||||
static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
#endif
|
||||
static struct connection *actual_connection = NULL;
|
||||
static struct connection *all_connections = NULL;
|
||||
@ -38,10 +37,13 @@ ecpg_get_connection_nr(const char *connection_name)
|
||||
{
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
ret = pthread_getspecific(actual_connection_key);
|
||||
/* if no connection in TSD for this thread, get the global default connection
|
||||
* and hope the user knows what they're doing (i.e. using their own mutex to
|
||||
* protect that connection from concurrent accesses */
|
||||
if(NULL == ret)
|
||||
|
||||
/*
|
||||
* if no connection in TSD for this thread, get the global default
|
||||
* connection and hope the user knows what they're doing (i.e. using
|
||||
* their own mutex to protect that connection from concurrent accesses
|
||||
*/
|
||||
if (NULL == ret)
|
||||
{
|
||||
ECPGlog("no TSD connection, going for global\n");
|
||||
ret = actual_connection;
|
||||
@ -76,13 +78,16 @@ ECPGget_connection(const char *connection_name)
|
||||
{
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
ret = pthread_getspecific(actual_connection_key);
|
||||
/* if no connection in TSD for this thread, get the global default connection
|
||||
* and hope the user knows what they're doing (i.e. using their own mutex to
|
||||
* protect that connection from concurrent accesses */
|
||||
if(NULL == ret)
|
||||
|
||||
/*
|
||||
* if no connection in TSD for this thread, get the global default
|
||||
* connection and hope the user knows what they're doing (i.e. using
|
||||
* their own mutex to protect that connection from concurrent accesses
|
||||
*/
|
||||
if (NULL == ret)
|
||||
{
|
||||
ECPGlog("no TSD connection here either, using global\n");
|
||||
ret = actual_connection;
|
||||
ret = actual_connection;
|
||||
}
|
||||
else
|
||||
ECPGlog("got TSD connection\n");
|
||||
@ -275,8 +280,8 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
|
||||
|
||||
/*
|
||||
* Informix uses an environment variable DBPATH that overrides the
|
||||
* connection parameters given here. We do the same with PG_DBPATH
|
||||
* as the syntax is different.
|
||||
* connection parameters given here. We do the same with PG_DBPATH as
|
||||
* the syntax is different.
|
||||
*/
|
||||
envname = getenv("PG_DBPATH");
|
||||
if (envname)
|
||||
@ -294,20 +299,20 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
|
||||
connection_name = "DEFAULT";
|
||||
|
||||
if (dbname != NULL)
|
||||
{
|
||||
{
|
||||
/* get the detail information out of dbname */
|
||||
if (strchr(dbname, '@') != NULL)
|
||||
{
|
||||
/* old style: dbname[@server][:port] */
|
||||
tmp = strrchr(dbname, ':');
|
||||
if (tmp != NULL) /* port number given */
|
||||
if (tmp != NULL) /* port number given */
|
||||
{
|
||||
port = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
tmp = strrchr(dbname, '@');
|
||||
if (tmp != NULL) /* host name given */
|
||||
if (tmp != NULL) /* host name given */
|
||||
{
|
||||
host = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.28 2005/08/24 10:34:19 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.29 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
#define POSTGRES_ECPG_INTERNAL
|
||||
#include "postgres_fe.h"
|
||||
@ -53,8 +53,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
/* We will have to decode the value */
|
||||
|
||||
/*
|
||||
* check for null value and set indicator accordingly, i.e. -1 if NULL
|
||||
* and 0 if not
|
||||
* check for null value and set indicator accordingly, i.e. -1 if NULL and
|
||||
* 0 if not
|
||||
*/
|
||||
if (PQgetisnull(results, act_tuple, act_field))
|
||||
value_for_indicator = -1;
|
||||
@ -85,8 +85,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
if (force_indicator == false)
|
||||
{
|
||||
/*
|
||||
* Informix has an additional way to specify NULLs
|
||||
* note that this uses special values to denote NULL
|
||||
* Informix has an additional way to specify NULLs note
|
||||
* that this uses special values to denote NULL
|
||||
*/
|
||||
ECPGset_noind_null(type, var + offset * act_tuple);
|
||||
}
|
||||
@ -424,8 +424,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
if (INFORMIX_MODE(compat))
|
||||
{
|
||||
/*
|
||||
* Informix wants its own NULL value here
|
||||
* instead of an error
|
||||
* Informix wants its own NULL value here instead
|
||||
* of an error
|
||||
*/
|
||||
ECPGset_noind_null(ECPGt_numeric, nres);
|
||||
}
|
||||
@ -471,8 +471,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
if (INFORMIX_MODE(compat))
|
||||
{
|
||||
/*
|
||||
* Informix wants its own NULL value here
|
||||
* instead of an error
|
||||
* Informix wants its own NULL value here instead
|
||||
* of an error
|
||||
*/
|
||||
ECPGset_noind_null(ECPGt_interval, ires);
|
||||
}
|
||||
@ -514,8 +514,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
if (INFORMIX_MODE(compat))
|
||||
{
|
||||
/*
|
||||
* Informix wants its own NULL value here
|
||||
* instead of an error
|
||||
* Informix wants its own NULL value here instead
|
||||
* of an error
|
||||
*/
|
||||
ECPGset_noind_null(ECPGt_date, &ddres);
|
||||
}
|
||||
@ -556,8 +556,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
if (INFORMIX_MODE(compat))
|
||||
{
|
||||
/*
|
||||
* Informix wants its own NULL value here
|
||||
* instead of an error
|
||||
* Informix wants its own NULL value here instead
|
||||
* of an error
|
||||
*/
|
||||
ECPGset_noind_null(ECPGt_timestamp, &tres);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.10 2003/11/29 19:52:08 pgsql Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.11 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
#define POSTGRES_ECPG_INTERNAL
|
||||
#include "postgres_fe.h"
|
||||
@ -49,7 +49,7 @@ ECPGraise(int line, int code, const char *sqlstate, const char *str)
|
||||
|
||||
case ECPG_INT_FORMAT:
|
||||
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted int type: %s line %d.", str, line);
|
||||
"Not correctly formatted int type: %s line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_UINT_FORMAT:
|
||||
@ -64,7 +64,7 @@ ECPGraise(int line, int code, const char *sqlstate, const char *str)
|
||||
|
||||
case ECPG_CONVERT_BOOL:
|
||||
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
|
||||
"Unable to convert %s to bool on line %d.", str, line);
|
||||
"Unable to convert %s to bool on line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_EMPTY:
|
||||
@ -84,12 +84,12 @@ ECPGraise(int line, int code, const char *sqlstate, const char *str)
|
||||
|
||||
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);
|
||||
"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);
|
||||
"Trying to insert an array of variables in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_NO_CONN:
|
||||
@ -129,7 +129,7 @@ ECPGraise(int line, int code, const char *sqlstate, const char *str)
|
||||
|
||||
case ECPG_VAR_NOT_CHAR:
|
||||
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
|
||||
"Variable is not a character type in line %d.", line);
|
||||
"Variable is not a character type in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_TRANS:
|
||||
@ -139,7 +139,7 @@ ECPGraise(int line, int code, const char *sqlstate, const char *str)
|
||||
|
||||
case ECPG_CONNECT:
|
||||
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
|
||||
"Could not connect to database %s in line %d.", str, line);
|
||||
"Could not connect to database %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -192,7 +192,7 @@ ECPGraise_backend(int line, PGresult *result, PGconn *conn, int compat)
|
||||
sqlca->sqlcode = ECPG_PGSQL;
|
||||
|
||||
ECPGlog("raising sqlstate %.*s in line %d, '%s'.\n",
|
||||
sizeof(sqlca->sqlstate), sqlca->sqlstate, line, sqlca->sqlerrm.sqlerrmc);
|
||||
sizeof(sqlca->sqlstate), sqlca->sqlstate, line, sqlca->sqlerrm.sqlerrmc);
|
||||
|
||||
/* free all memory we have allocated for the user */
|
||||
ECPGfree_auto_mem();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.42 2005/07/04 19:05:45 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.43 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
/*
|
||||
* The aim is to get a simpler inteface to the database routines.
|
||||
@ -110,8 +110,7 @@ ECPGget_variable(va_list APREF, enum ECPGttype type, struct variable * var, bool
|
||||
var->ind_value = var->ind_pointer;
|
||||
|
||||
/*
|
||||
* negative values are used to indicate an array without given
|
||||
* bounds
|
||||
* negative values are used to indicate an array without given bounds
|
||||
*/
|
||||
/* reset to zero for us */
|
||||
if (var->ind_arrsize < 0)
|
||||
@ -120,6 +119,7 @@ ECPGget_variable(va_list APREF, enum ECPGttype type, struct variable * var, bool
|
||||
var->ind_varcharsize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#undef APREF
|
||||
|
||||
/*
|
||||
@ -267,9 +267,8 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
|
||||
if ((stmt->connection->cache_head) == NULL)
|
||||
{
|
||||
/*
|
||||
* Text like types are not an array for ecpg, but postgres counts
|
||||
* them as an array. This define reminds you to not 'correct'
|
||||
* these values.
|
||||
* Text like types are not an array for ecpg, but postgres counts them
|
||||
* as an array. This define reminds you to not 'correct' these values.
|
||||
*/
|
||||
#define not_an_array_in_ecpg ECPG_ARRAY_NONE
|
||||
|
||||
@ -464,7 +463,7 @@ ECPGstore_result(const PGresult *results, int act_field,
|
||||
int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
|
||||
|
||||
if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno,
|
||||
var->type, var->ind_type, current_data_location,
|
||||
var->type, var->ind_type, current_data_location,
|
||||
var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
|
||||
status = false;
|
||||
else
|
||||
@ -499,8 +498,8 @@ ECPGstore_input(const int lineno, const bool force_indicator, const struct varia
|
||||
char *newcopy = NULL;
|
||||
|
||||
/*
|
||||
* arrays are not possible unless the attribute is an array too FIXME:
|
||||
* we do not know if the attribute is an array here
|
||||
* arrays are not possible unless the attribute is an array too FIXME: we
|
||||
* do not know if the attribute is an array here
|
||||
*/
|
||||
#if 0
|
||||
if (var->arrsize > 1 &&...)
|
||||
@ -772,8 +771,7 @@ ECPGstore_input(const int lineno, const bool force_indicator, const struct varia
|
||||
sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
|
||||
|
||||
/*
|
||||
* this is necessary since sizeof(C++'s
|
||||
* bool)==sizeof(int)
|
||||
* this is necessary since sizeof(C++'s bool)==sizeof(int)
|
||||
*/
|
||||
else if (var->offset == sizeof(int))
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
@ -1064,10 +1062,9 @@ ECPGexecute(struct statement * stmt)
|
||||
copiedquery = ECPGstrdup(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.
|
||||
* 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;
|
||||
|
||||
@ -1082,14 +1079,14 @@ ECPGexecute(struct statement * stmt)
|
||||
tobeinserted = NULL;
|
||||
|
||||
/*
|
||||
* A descriptor is a special case since it contains many variables
|
||||
* but is listed only once.
|
||||
* A descriptor is a special case since it contains many variables but
|
||||
* is listed only once.
|
||||
*/
|
||||
if (var->type == ECPGt_descriptor)
|
||||
{
|
||||
/*
|
||||
* We create an additional variable list here, so the same
|
||||
* logic applies.
|
||||
* We create an additional variable list here, so the same logic
|
||||
* applies.
|
||||
*/
|
||||
struct variable desc_inlist;
|
||||
struct descriptor *desc;
|
||||
@ -1156,8 +1153,8 @@ ECPGexecute(struct statement * stmt)
|
||||
if (tobeinserted)
|
||||
{
|
||||
/*
|
||||
* Now tobeinserted points to an area that is to be inserted
|
||||
* at the first %s
|
||||
* Now tobeinserted points to an area that is to be inserted at
|
||||
* the first %s
|
||||
*/
|
||||
if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
|
||||
return false;
|
||||
@ -1166,8 +1163,8 @@ ECPGexecute(struct statement * stmt)
|
||||
if ((p = next_insert(newcopy + hostvarl)) == NULL)
|
||||
{
|
||||
/*
|
||||
* We have an argument but we dont have the matched up
|
||||
* string in the string
|
||||
* We have an argument but we dont have the matched up string
|
||||
* in the string
|
||||
*/
|
||||
ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
|
||||
return false;
|
||||
@ -1178,8 +1175,8 @@ ECPGexecute(struct statement * stmt)
|
||||
hostvarl = strlen(newcopy);
|
||||
|
||||
/*
|
||||
* The strange thing in the second argument is the rest of
|
||||
* the string from the old string
|
||||
* The strange thing in the second argument is the rest of the
|
||||
* string from the old string
|
||||
*/
|
||||
strcat(newcopy,
|
||||
copiedquery
|
||||
@ -1188,9 +1185,9 @@ ECPGexecute(struct statement * stmt)
|
||||
}
|
||||
|
||||
/*
|
||||
* Now everything is safely copied to the newcopy. Lets free
|
||||
* the oldcopy and let the copiedquery get the var->value from
|
||||
* the newcopy.
|
||||
* Now everything is safely copied to the newcopy. Lets free the
|
||||
* oldcopy and let the copiedquery get the var->value from the
|
||||
* newcopy.
|
||||
*/
|
||||
if (malloced)
|
||||
{
|
||||
|
@ -125,8 +125,9 @@ PGresult **ECPGdescriptor_lvalue(int line, const char *descriptor);
|
||||
bool ECPGstore_result(const PGresult *results, int act_field,
|
||||
const struct statement * stmt, struct variable * var);
|
||||
bool ECPGstore_input(const int, const bool, const struct variable *, const char **, bool *);
|
||||
|
||||
#if defined(__GNUC__) && (defined (__powerpc__) || defined(__amd64__) || defined(__x86_64__))
|
||||
// work around a gcc/ABI bug with va_lists on ppc+amd64
|
||||
/* work around a gcc/ABI bug with va_lists on ppc+amd64 */
|
||||
void ECPGget_variable(va_list, enum ECPGttype, struct variable *, bool);
|
||||
#else
|
||||
void ECPGget_variable(va_list *, enum ECPGttype, struct variable *, bool);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.6 2004/12/30 09:36:37 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.7 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
#define POSTGRES_ECPG_INTERNAL
|
||||
#include "postgres_fe.h"
|
||||
@ -50,7 +50,7 @@ ECPGstrdup(const char *string, int lineno)
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
new = strdup(string);
|
||||
if (!new)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.25 2005/09/12 11:57:53 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.26 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
#define POSTGRES_ECPG_INTERNAL
|
||||
#include "postgres_fe.h"
|
||||
@ -58,7 +58,6 @@ static struct sqlca_t sqlca_init =
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
static pthread_key_t sqlca_key;
|
||||
static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
#else
|
||||
static struct sqlca_t sqlca =
|
||||
{
|
||||
@ -122,8 +121,7 @@ static void
|
||||
ecpg_sqlca_key_destructor(void *arg)
|
||||
{
|
||||
if (arg != NULL)
|
||||
free(arg); /* sqlca structure allocated in
|
||||
* ECPGget_sqlca */
|
||||
free(arg); /* sqlca structure allocated in ECPGget_sqlca */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -186,10 +184,11 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
|
||||
/* if we have no connection we just simulate the command */
|
||||
if (con && con->connection)
|
||||
{
|
||||
/* If we got a transaction command but have no open transaction,
|
||||
* we have to start one, unless we are in autocommit, where the
|
||||
* developers have to take care themselves.
|
||||
* However, if the command is a begin statement, we just execute it once.
|
||||
/*
|
||||
* If we got a transaction command but have no open transaction, we
|
||||
* have to start one, unless we are in autocommit, where the
|
||||
* developers have to take care themselves. However, if the command is
|
||||
* a begin statement, we just execute it once.
|
||||
*/
|
||||
if (con->committed && !con->autocommit && strncmp(transaction, "begin", 5) != 0 && strncmp(transaction, "start", 5) != 0)
|
||||
{
|
||||
@ -201,7 +200,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
|
||||
res = PQexec(con->connection, transaction);
|
||||
if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
@ -257,7 +256,7 @@ ECPGlog(const char *format,...)
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(f, "[%d]: %s", (int)getpid(), format);
|
||||
sprintf(f, "[%d]: %s", (int) getpid(), format);
|
||||
|
||||
va_start(ap, format);
|
||||
vfprintf(debugstream, f, ap);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.13 2004/10/05 10:48:37 meskes Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.14 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
#define POSTGRES_ECPG_INTERNAL
|
||||
#include "postgres_fe.h"
|
||||
@ -46,9 +46,9 @@ replace_variables(char *text)
|
||||
|
||||
if (!string && *ptr == ':')
|
||||
{
|
||||
if (ptr[1]==':')
|
||||
ptr+=2; /* skip '::' */
|
||||
else
|
||||
if (ptr[1] == ':')
|
||||
ptr += 2; /* skip '::' */
|
||||
else
|
||||
{
|
||||
*ptr = '?';
|
||||
for (++ptr; *ptr && isvarchar(*ptr); ptr++)
|
||||
@ -120,8 +120,8 @@ ECPGdeallocate(int lineno, int c, char *name)
|
||||
if (INFORMIX_MODE(compat))
|
||||
{
|
||||
/*
|
||||
* Just ignore all errors since we do not know the list of cursors
|
||||
* we are allowed to free. We have to trust the software.
|
||||
* Just ignore all errors since we do not know the list of cursors we
|
||||
* are allowed to free. We have to trust the software.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
@ -44,10 +44,10 @@ enum ECPGttype
|
||||
ECPGt_bool,
|
||||
ECPGt_float, ECPGt_double,
|
||||
ECPGt_varchar, ECPGt_varchar2,
|
||||
ECPGt_numeric, /* this is a decimal that stores its
|
||||
* digits in a malloced array */
|
||||
ECPGt_decimal, /* this is a decimal that stores its
|
||||
* digits in a fixed array */
|
||||
ECPGt_numeric, /* this is a decimal that stores its digits in
|
||||
* a malloced array */
|
||||
ECPGt_decimal, /* this is a decimal that stores its digits in
|
||||
* a fixed array */
|
||||
ECPGt_date,
|
||||
ECPGt_timestamp,
|
||||
ECPGt_interval,
|
||||
|
@ -4,15 +4,12 @@
|
||||
typedef struct
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int64 time; /* all time units other than months and
|
||||
* years */
|
||||
int64 time; /* all time units other than months and years */
|
||||
#else
|
||||
double time; /* all time units other than months and
|
||||
* years */
|
||||
double time; /* all time units other than months and years */
|
||||
#endif
|
||||
long month; /* months and years, after time for
|
||||
* alignment */
|
||||
} interval;
|
||||
long month; /* months and years, after time for alignment */
|
||||
} interval;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -14,35 +14,31 @@
|
||||
typedef unsigned char NumericDigit;
|
||||
typedef struct
|
||||
{
|
||||
int ndigits; /* number of digits in digits[] - can be
|
||||
* 0! */
|
||||
int ndigits; /* number of digits in digits[] - can be 0! */
|
||||
int weight; /* weight of first digit */
|
||||
int rscale; /* result scale */
|
||||
int dscale; /* display scale */
|
||||
int sign; /* NUMERIC_POS, NUMERIC_NEG, or
|
||||
* NUMERIC_NAN */
|
||||
int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
|
||||
NumericDigit *buf; /* start of alloc'd space for digits[] */
|
||||
NumericDigit *digits; /* decimal digits */
|
||||
} numeric;
|
||||
} numeric;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ndigits; /* number of digits in digits[] - can be
|
||||
* 0! */
|
||||
int ndigits; /* number of digits in digits[] - can be 0! */
|
||||
int weight; /* weight of first digit */
|
||||
int rscale; /* result scale */
|
||||
int dscale; /* display scale */
|
||||
int sign; /* NUMERIC_POS, NUMERIC_NEG, or
|
||||
* NUMERIC_NAN */
|
||||
int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
|
||||
NumericDigit digits[DECSIZE]; /* decimal digits */
|
||||
} decimal;
|
||||
} decimal;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
numeric *PGTYPESnumeric_new(void);
|
||||
numeric * PGTYPESnumeric_new(void);
|
||||
void PGTYPESnumeric_free(numeric *);
|
||||
numeric *PGTYPESnumeric_from_asc(char *, char **);
|
||||
char *PGTYPESnumeric_to_asc(numeric *, int);
|
||||
|
@ -6,7 +6,6 @@
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
typedef int64 timestamp;
|
||||
typedef int64 TimestampTz;
|
||||
|
||||
#else
|
||||
typedef double timestamp;
|
||||
typedef double TimestampTz;
|
||||
@ -23,8 +22,8 @@ extern int PGTYPEStimestamp_sub(timestamp *, timestamp *, interval *);
|
||||
extern int PGTYPEStimestamp_fmt_asc(timestamp *, char *, int, char *);
|
||||
extern void PGTYPEStimestamp_current(timestamp *);
|
||||
extern int PGTYPEStimestamp_defmt_asc(char *, char *, timestamp *);
|
||||
extern int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout);
|
||||
extern int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout);
|
||||
extern int PGTYPEStimestamp_add_interval(timestamp * tin, interval * span, timestamp * tout);
|
||||
extern int PGTYPEStimestamp_sub_interval(timestamp * tin, interval * span, timestamp * tout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -41,8 +41,7 @@ pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **outp
|
||||
if (i + 1 <= *pstr_len)
|
||||
{
|
||||
/*
|
||||
* copy over i + 1 bytes, that includes the tailing
|
||||
* terminator
|
||||
* copy over i + 1 bytes, that includes the tailing terminator
|
||||
*/
|
||||
strncpy(*output, replace_val.str_val, i + 1);
|
||||
*pstr_len -= i;
|
||||
|
@ -25,7 +25,7 @@ PGTYPESdate_from_timestamp(timestamp dt)
|
||||
dDate = (dt / USECS_PER_DAY);
|
||||
#else
|
||||
/* Seconds to days */
|
||||
dDate = (dt / (double)SECS_PER_DAY);
|
||||
dDate = (dt / (double) SECS_PER_DAY);
|
||||
#endif
|
||||
|
||||
return dDate;
|
||||
@ -58,7 +58,7 @@ PGTYPESdate_from_asc(char *str, char **endptr)
|
||||
}
|
||||
|
||||
if (ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf, ptr) != 0 ||
|
||||
DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp, EuroDates) != 0)
|
||||
DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp, EuroDates) != 0)
|
||||
{
|
||||
errno = PGTYPES_DATE_BAD_DATE;
|
||||
return INT_MIN;
|
||||
@ -111,7 +111,7 @@ PGTYPESdate_julmdy(date jd, int *mdy)
|
||||
}
|
||||
|
||||
void
|
||||
PGTYPESdate_mdyjul(int *mdy, date *jdate)
|
||||
PGTYPESdate_mdyjul(int *mdy, date * jdate)
|
||||
{
|
||||
/* month is mdy[0] */
|
||||
/* day is mdy[1] */
|
||||
@ -131,7 +131,7 @@ PGTYPESdate_dayofweek(date dDate)
|
||||
}
|
||||
|
||||
void
|
||||
PGTYPESdate_today(date *d)
|
||||
PGTYPESdate_today(date * d)
|
||||
{
|
||||
struct tm ts;
|
||||
|
||||
@ -143,8 +143,7 @@ PGTYPESdate_today(date *d)
|
||||
#define PGTYPES_DATE_NUM_MAX_DIGITS 20 /* should suffice for most
|
||||
* years... */
|
||||
|
||||
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ 1 /* LZ means "leading
|
||||
* zeroes" */
|
||||
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ 1 /* LZ means "leading zeroes" */
|
||||
#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT 2
|
||||
#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ 3
|
||||
#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT 4
|
||||
@ -161,8 +160,8 @@ PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf)
|
||||
} mapping[] =
|
||||
{
|
||||
/*
|
||||
* format items have to be sorted according to their length, since
|
||||
* the first pattern that matches gets replaced by its value
|
||||
* format items have to be sorted according to their length, since the
|
||||
* first pattern that matches gets replaced by its value
|
||||
*/
|
||||
{
|
||||
"ddd", PGTYPES_FMTDATE_DOW_LITERAL_SHORT
|
||||
@ -290,8 +289,7 @@ PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf)
|
||||
|
||||
/*
|
||||
* doesn't happen (we set replace_type to
|
||||
* PGTYPES_TYPE_STRING_CONSTANT in case of an error
|
||||
* above)
|
||||
* PGTYPES_TYPE_STRING_CONSTANT in case of an error above)
|
||||
*/
|
||||
break;
|
||||
}
|
||||
@ -316,11 +314,11 @@ PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf)
|
||||
|
||||
#define PGTYPES_DATE_MONTH_MAXLENGTH 20 /* probably even less :-) */
|
||||
int
|
||||
PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
PGTYPESdate_defmt_asc(date * d, char *fmt, char *str)
|
||||
{
|
||||
/*
|
||||
* token[2] = { 4,6 } means that token 2 starts at position 4 and ends
|
||||
* at (including) position 6
|
||||
* token[2] = { 4,6 } means that token 2 starts at position 4 and ends at
|
||||
* (including) position 6
|
||||
*/
|
||||
int token[3][2];
|
||||
int token_values[3] = {-1, -1, -1};
|
||||
@ -334,7 +332,7 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
char *str_copy;
|
||||
struct tm tm;
|
||||
|
||||
tm.tm_year = tm.tm_mon = tm.tm_mday = 0; /* keep compiler quiet */
|
||||
tm.tm_year = tm.tm_mon = tm.tm_mday = 0; /* keep compiler quiet */
|
||||
|
||||
if (!d || !str || !fmt)
|
||||
{
|
||||
@ -427,8 +425,8 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
/* okay, this really is the special case */
|
||||
|
||||
/*
|
||||
* as long as the string, one additional byte for the terminator
|
||||
* and 2 for the delimiters between the 3 fiedls
|
||||
* as long as the string, one additional byte for the terminator and 2
|
||||
* for the delimiters between the 3 fiedls
|
||||
*/
|
||||
str_copy = pgtypes_alloc(strlen(str) + 1 + 2);
|
||||
if (!str_copy)
|
||||
@ -465,9 +463,9 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
target_pos = 0;
|
||||
|
||||
/*
|
||||
* XXX: Here we could calculate the positions of the tokens and
|
||||
* save the for loop down there where we again check with
|
||||
* isdigit() for digits.
|
||||
* XXX: Here we could calculate the positions of the tokens and save
|
||||
* the for loop down there where we again check with isdigit() for
|
||||
* digits.
|
||||
*/
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
@ -521,8 +519,8 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
}
|
||||
|
||||
/*
|
||||
* we're at the end of the input string, but maybe we are still
|
||||
* reading a number...
|
||||
* we're at the end of the input string, but maybe we are still reading a
|
||||
* number...
|
||||
*/
|
||||
if (reading_digit)
|
||||
{
|
||||
@ -534,8 +532,8 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
if (token_count < 2)
|
||||
{
|
||||
/*
|
||||
* not all tokens found, no way to find 2 missing tokens with
|
||||
* string matches
|
||||
* not all tokens found, no way to find 2 missing tokens with string
|
||||
* matches
|
||||
*/
|
||||
free(str_copy);
|
||||
errno = PGTYPES_DATE_ERR_ENOTDMY;
|
||||
@ -546,8 +544,7 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
{
|
||||
/*
|
||||
* not all tokens found but we may find another one with string
|
||||
* matches by testing for the months names and months
|
||||
* abbreviations
|
||||
* matches by testing for the months names and months abbreviations
|
||||
*/
|
||||
char *month_lower_tmp = pgtypes_alloc(PGTYPES_DATE_MONTH_MAXLENGTH);
|
||||
char *start_pos;
|
||||
@ -579,8 +576,8 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
offset = start_pos - str_copy;
|
||||
|
||||
/*
|
||||
* sort the new token into the numeric tokens, shift them
|
||||
* if necessary
|
||||
* sort the new token into the numeric tokens, shift them if
|
||||
* necessary
|
||||
*/
|
||||
if (offset < token[0][0])
|
||||
{
|
||||
@ -602,8 +599,8 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
token[token_count][1] = offset + strlen(month_lower_tmp) - 1;
|
||||
|
||||
/*
|
||||
* the value is the index of the month in the array of
|
||||
* months + 1 (January is month 0)
|
||||
* the value is the index of the month in the array of months
|
||||
* + 1 (January is month 0)
|
||||
*/
|
||||
token_values[token_count] = i + 1;
|
||||
found = 1;
|
||||
@ -611,9 +608,9 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
}
|
||||
|
||||
/*
|
||||
* evil[tm] hack: if we read the pgtypes_date_months and
|
||||
* haven't found a match, reset list to point to
|
||||
* pgtypes_date_months_short and reset the counter variable i
|
||||
* evil[tm] hack: if we read the pgtypes_date_months and haven't
|
||||
* found a match, reset list to point to pgtypes_date_months_short
|
||||
* and reset the counter variable i
|
||||
*/
|
||||
if (list == pgtypes_date_months)
|
||||
{
|
||||
@ -636,13 +633,12 @@ PGTYPESdate_defmt_asc(date *d, char *fmt, char *str)
|
||||
* here we found a month. token[token_count] and
|
||||
* token_values[token_count] reflect the month's details.
|
||||
*
|
||||
* only the month can be specified with a literal. Here we can do a
|
||||
* quick check if the month is at the right position according to
|
||||
* the format string because we can check if the token that we
|
||||
* expect to be the month is at the position of the only token
|
||||
* that already has a value. If we wouldn't check here we could
|
||||
* say "December 4 1990" with a fmt string of "dd mm yy" for 12
|
||||
* April 1990.
|
||||
* only the month can be specified with a literal. Here we can do a quick
|
||||
* check if the month is at the right position according to the format
|
||||
* string because we can check if the token that we expect to be the
|
||||
* month is at the position of the only token that already has a
|
||||
* value. If we wouldn't check here we could say "December 4 1990"
|
||||
* with a fmt string of "dd mm yy" for 12 April 1990.
|
||||
*/
|
||||
if (fmt_token_order[token_count] != 'm')
|
||||
{
|
||||
|
@ -8,7 +8,6 @@
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
|
||||
typedef int32 fsec_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef double fsec_t;
|
||||
@ -17,7 +16,6 @@ typedef double fsec_t;
|
||||
/* note: this is also used for rounding off intervals */
|
||||
#define TS_PREC_INV 1000000.0
|
||||
#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
|
||||
|
||||
#endif
|
||||
|
||||
#define USE_POSTGRES_DATES 0
|
||||
@ -168,10 +166,10 @@ typedef double fsec_t;
|
||||
#define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
|
||||
#define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
|
||||
|
||||
#define MAXDATELEN 51 /* maximum possible length of an input
|
||||
* date string (not counting tr. null) */
|
||||
#define MAXDATEFIELDS 25 /* maximum possible number of fields in a
|
||||
* date string */
|
||||
#define MAXDATELEN 51 /* maximum possible length of an input date
|
||||
* string (not counting tr. null) */
|
||||
#define MAXDATEFIELDS 25 /* maximum possible number of fields in a date
|
||||
* string */
|
||||
#define TOKMAXLEN 10 /* only this many chars are stored in
|
||||
* datetktbl */
|
||||
|
||||
@ -221,12 +219,12 @@ do { \
|
||||
|
||||
/* in both timestamp.h and ecpg/dt.h */
|
||||
#define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */
|
||||
#define MONTHS_PER_YEAR 12
|
||||
#define MONTHS_PER_YEAR 12
|
||||
/*
|
||||
* DAYS_PER_MONTH is very imprecise. The more accurate value is
|
||||
* 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only
|
||||
* return an integral number of days, but someday perhaps we should
|
||||
* also return a 'time' value to be used as well. ISO 8601 suggests
|
||||
* also return a 'time' value to be used as well. ISO 8601 suggests
|
||||
* 30 days.
|
||||
*/
|
||||
#define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */
|
||||
@ -239,7 +237,7 @@ do { \
|
||||
*/
|
||||
#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */
|
||||
#define SECS_PER_DAY 86400
|
||||
#define SECS_PER_HOUR 3600
|
||||
#define SECS_PER_HOUR 3600
|
||||
#define SECS_PER_MINUTE 60
|
||||
#define MINS_PER_HOUR 60
|
||||
|
||||
@ -291,7 +289,6 @@ do { \
|
||||
|
||||
#define DT_NOBEGIN (-INT64CONST(0x7fffffffffffffff) - 1)
|
||||
#define DT_NOEND (INT64CONST(0x7fffffffffffffff))
|
||||
|
||||
#else
|
||||
|
||||
#ifdef HUGE_VAL
|
||||
@ -311,15 +308,15 @@ do { \
|
||||
|
||||
int DecodeTimeOnly(char **field, int *ftype,
|
||||
int nf, int *dtype,
|
||||
struct tm *tm, fsec_t *fsec, int *tzp);
|
||||
struct tm * tm, fsec_t *fsec, int *tzp);
|
||||
|
||||
int DecodeInterval(char **field, int *ftype,
|
||||
int nf, int *dtype,
|
||||
struct tm *tm, fsec_t *fsec);
|
||||
struct tm * tm, fsec_t *fsec);
|
||||
|
||||
int EncodeTimeOnly(struct tm *tm, fsec_t fsec, int *tzp, int style, char *str);
|
||||
int EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool);
|
||||
int EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str);
|
||||
int EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str);
|
||||
int EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool);
|
||||
int EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str);
|
||||
|
||||
int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
|
||||
|
||||
@ -339,6 +336,6 @@ extern char *pgtypes_date_weekdays_short[];
|
||||
extern char *pgtypes_date_months[];
|
||||
extern char *months[];
|
||||
extern char *days[];
|
||||
extern int day_tab[2][13];
|
||||
extern int day_tab[2][13];
|
||||
|
||||
#endif /* DT_H */
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "dt.h"
|
||||
#include "pgtypes_timestamp.h"
|
||||
|
||||
int day_tab[2][13] = {
|
||||
int day_tab[2][13] = {
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}};
|
||||
|
||||
@ -240,8 +240,7 @@ static datetkn datetktbl[] = {
|
||||
{"lhdt", DTZ, POS(44)}, /* Lord Howe Daylight Time, Australia */
|
||||
{"lhst", TZ, POS(42)}, /* Lord Howe Standard Time, Australia */
|
||||
{"ligt", TZ, POS(40)}, /* From Melbourne, Australia */
|
||||
{"lint", TZ, POS(56)}, /* Line Islands Time (Kiribati; +14
|
||||
* hours!) */
|
||||
{"lint", TZ, POS(56)}, /* Line Islands Time (Kiribati; +14 hours!) */
|
||||
{"lkt", TZ, POS(24)}, /* Lanka Time */
|
||||
{"m", UNITS, DTK_MONTH}, /* "month" for ISO input */
|
||||
{"magst", DTZ, POS(48)}, /* Magadan Summer Time */
|
||||
@ -686,7 +685,7 @@ DecodeSpecial(int field, char *lowtoken, int *val)
|
||||
* Encode date as local time.
|
||||
*/
|
||||
int
|
||||
EncodeDateOnly(struct tm *tm, int style, char *str, bool EuroDates)
|
||||
EncodeDateOnly(struct tm * tm, int style, char *str, bool EuroDates)
|
||||
{
|
||||
if (tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR)
|
||||
return -1;
|
||||
@ -700,7 +699,7 @@ EncodeDateOnly(struct tm *tm, int style, char *str, bool EuroDates)
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
else
|
||||
sprintf(str, "%04d-%02d-%02d %s",
|
||||
-(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
|
||||
-(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
|
||||
break;
|
||||
|
||||
case USE_SQL_DATES:
|
||||
@ -766,7 +765,7 @@ TrimTrailingZeros(char *str)
|
||||
* European - dd/mm/yyyy
|
||||
*/
|
||||
int
|
||||
EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool EuroDates)
|
||||
EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool EuroDates)
|
||||
{
|
||||
int day,
|
||||
hour,
|
||||
@ -778,15 +777,15 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
/* Compatible with ISO-8601 date formats */
|
||||
|
||||
sprintf(str, "%04d-%02d-%02d %02d:%02d",
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
* In float mode, don't print fractional seconds before 1 AD, since
|
||||
* it's unlikely there's any precision left ...
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (fsec != 0)
|
||||
@ -806,10 +805,10 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
sprintf(str + strlen(str), " BC");
|
||||
|
||||
/*
|
||||
* tzp == NULL indicates that we don't want *any* time zone
|
||||
* info in the output string. *tzn != NULL indicates that we
|
||||
* have alpha time zone info available. tm_isdst != -1
|
||||
* indicates that we have a valid time zone translation.
|
||||
* tzp == NULL indicates that we don't want *any* time zone info
|
||||
* in the output string. *tzn != NULL indicates that we have alpha
|
||||
* time zone info available. tm_isdst != -1 indicates that we have
|
||||
* a valid time zone translation.
|
||||
*/
|
||||
if (tzp != NULL && tm->tm_isdst >= 0)
|
||||
{
|
||||
@ -828,15 +827,15 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
|
||||
|
||||
sprintf(str + 5, "/%04d %02d:%02d",
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||
tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
* In float mode, don't print fractional seconds before 1 AD, since
|
||||
* it's unlikely there's any precision left ...
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (fsec != 0)
|
||||
@ -874,15 +873,15 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);
|
||||
|
||||
sprintf(str + 5, ".%04d %02d:%02d",
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||
tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
* In float mode, don't print fractional seconds before 1 AD, since
|
||||
* it's unlikely there's any precision left ...
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (fsec != 0)
|
||||
@ -932,11 +931,11 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
sprintf(str + 10, " %02d:%02d", tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
* In float mode, don't print fractional seconds before 1 AD, since
|
||||
* it's unlikely there's any precision left ...
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (fsec != 0)
|
||||
@ -953,7 +952,7 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
sprintf(str + strlen(str), ":%02d", tm->tm_sec);
|
||||
|
||||
sprintf(str + strlen(str), " %04d",
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1));
|
||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1));
|
||||
if (tm->tm_year <= 0)
|
||||
sprintf(str + strlen(str), " BC");
|
||||
|
||||
@ -965,10 +964,9 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
{
|
||||
/*
|
||||
* We have a time zone, but no string version. Use the
|
||||
* numeric form, but be sure to include a leading
|
||||
* space to avoid formatting something which would be
|
||||
* rejected by the date/time parser later. - thomas
|
||||
* 2001-10-19
|
||||
* numeric form, but be sure to include a leading space to
|
||||
* avoid formatting something which would be rejected by
|
||||
* the date/time parser later. - thomas 2001-10-19
|
||||
*/
|
||||
hour = -(*tzp / SECS_PER_HOUR);
|
||||
min = (abs(*tzp) / MINS_PER_HOUR) % MINS_PER_HOUR;
|
||||
@ -982,7 +980,7 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, int *tzp, char **tzn, int style, char
|
||||
} /* EncodeDateTime() */
|
||||
|
||||
void
|
||||
GetEpochTime(struct tm *tm)
|
||||
GetEpochTime(struct tm * tm)
|
||||
{
|
||||
struct tm *t0;
|
||||
time_t epoch = 0;
|
||||
@ -1004,7 +1002,7 @@ GetEpochTime(struct tm *tm)
|
||||
} /* GetEpochTime() */
|
||||
|
||||
static void
|
||||
abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
|
||||
abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
|
||||
{
|
||||
time_t time = (time_t) _time;
|
||||
struct tm *tx;
|
||||
@ -1035,15 +1033,13 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
|
||||
*tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
|
||||
|
||||
/*
|
||||
* XXX FreeBSD man pages indicate that this should work - tgl
|
||||
* 97/04/23
|
||||
* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23
|
||||
*/
|
||||
if (tzn != NULL)
|
||||
{
|
||||
/*
|
||||
* Copy no more than MAXTZLEN bytes of timezone to tzn, in
|
||||
* case it contains an error message, which doesn't fit in the
|
||||
* buffer
|
||||
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
|
||||
* contains an error message, which doesn't fit in the buffer
|
||||
*/
|
||||
StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1);
|
||||
if (strlen(tm->tm_zone) > MAXTZLEN)
|
||||
@ -1060,9 +1056,8 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
|
||||
if (tzn != NULL)
|
||||
{
|
||||
/*
|
||||
* Copy no more than MAXTZLEN bytes of timezone to tzn, in
|
||||
* case it contains an error message, which doesn't fit in the
|
||||
* buffer
|
||||
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
|
||||
* contains an error message, which doesn't fit in the buffer
|
||||
*/
|
||||
StrNCpy(*tzn, TZNAME_GLOBAL[tm->tm_isdst], MAXTZLEN + 1);
|
||||
if (strlen(TZNAME_GLOBAL[tm->tm_isdst]) > MAXTZLEN)
|
||||
@ -1085,7 +1080,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentDateTime(struct tm *tm)
|
||||
GetCurrentDateTime(struct tm * tm)
|
||||
{
|
||||
int tz;
|
||||
|
||||
@ -1104,7 +1099,7 @@ GetCurrentDateTime(struct tm *tm)
|
||||
* the *only* call of mktime() in the backend.
|
||||
*/
|
||||
static int
|
||||
DetermineLocalTimeZone(struct tm *tm)
|
||||
DetermineLocalTimeZone(struct tm * tm)
|
||||
{
|
||||
int tz;
|
||||
|
||||
@ -1113,10 +1108,9 @@ DetermineLocalTimeZone(struct tm *tm)
|
||||
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
|
||||
|
||||
/*
|
||||
* Some buggy mktime() implementations may change the
|
||||
* year/month/day when given a time right at a DST boundary. To
|
||||
* prevent corruption of the caller's data, give mktime() a
|
||||
* copy...
|
||||
* Some buggy mktime() implementations may change the year/month/day
|
||||
* when given a time right at a DST boundary. To prevent corruption
|
||||
* of the caller's data, give mktime() a copy...
|
||||
*/
|
||||
struct tm tt,
|
||||
*tmp = &tt;
|
||||
@ -1129,7 +1123,7 @@ DetermineLocalTimeZone(struct tm *tm)
|
||||
/* indicate timezone unknown */
|
||||
tmp->tm_isdst = -1;
|
||||
|
||||
if (mktime(tmp) != (time_t)-1 && tmp->tm_isdst >= 0)
|
||||
if (mktime(tmp) != (time_t) -1 && tmp->tm_isdst >= 0)
|
||||
{
|
||||
/* mktime() succeeded, trust its result */
|
||||
tm->tm_isdst = tmp->tm_isdst;
|
||||
@ -1165,8 +1159,8 @@ DetermineLocalTimeZone(struct tm *tm)
|
||||
mytime = (time_t) mysec;
|
||||
|
||||
/*
|
||||
* Use localtime to convert that time_t to broken-down time,
|
||||
* and reassemble to get a representation of local time.
|
||||
* Use localtime to convert that time_t to broken-down time, and
|
||||
* reassemble to get a representation of local time.
|
||||
*/
|
||||
tmp = localtime(&mytime);
|
||||
day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
|
||||
@ -1180,21 +1174,20 @@ DetermineLocalTimeZone(struct tm *tm)
|
||||
delta1 = mysec - locsec;
|
||||
|
||||
/*
|
||||
* However, if that GMT time and the local time we are
|
||||
* actually interested in are on opposite sides of a
|
||||
* daylight-savings-time transition, then this is not the time
|
||||
* offset we want. So, adjust the time_t to be what we think
|
||||
* the GMT time corresponding to our target local time is, and
|
||||
* repeat the localtime() call and delta calculation. We may
|
||||
* have to do it twice before we have a trustworthy delta.
|
||||
* However, if that GMT time and the local time we are actually
|
||||
* interested in are on opposite sides of a daylight-savings-time
|
||||
* transition, then this is not the time offset we want. So,
|
||||
* adjust the time_t to be what we think the GMT time
|
||||
* corresponding to our target local time is, and repeat the
|
||||
* localtime() call and delta calculation. We may have to do it
|
||||
* twice before we have a trustworthy delta.
|
||||
*
|
||||
* Note: think not to put a loop here, since if we've been given
|
||||
* an "impossible" local time (in the gap during a
|
||||
* spring-forward transition) we'd never get out of the loop.
|
||||
* Twice is enough to give the behavior we want, which is that
|
||||
* "impossible" times are taken as standard time, while at a
|
||||
* fall-back boundary ambiguous times are also taken as
|
||||
* standard.
|
||||
* Note: think not to put a loop here, since if we've been given an
|
||||
* "impossible" local time (in the gap during a spring-forward
|
||||
* transition) we'd never get out of the loop. Twice is enough to
|
||||
* give the behavior we want, which is that "impossible" times are
|
||||
* taken as standard time, while at a fall-back boundary ambiguous
|
||||
* times are also taken as standard.
|
||||
*/
|
||||
mysec += delta1;
|
||||
mytime = (time_t) mysec;
|
||||
@ -1268,13 +1261,13 @@ dt2time(double jd, int *hour, int *min, int *sec, fsec_t *fsec)
|
||||
*/
|
||||
static int
|
||||
DecodeNumberField(int len, char *str, int fmask,
|
||||
int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
int *tmask, struct tm * tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
/*
|
||||
* Have a decimal point? Then this is a date or something with a
|
||||
* seconds field...
|
||||
* Have a decimal point? Then this is a date or something with a seconds
|
||||
* field...
|
||||
*/
|
||||
if ((cp = strchr(str, '.')) != NULL)
|
||||
{
|
||||
@ -1375,7 +1368,7 @@ int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
*/
|
||||
static int
|
||||
DecodeNumber(int flen, char *str, int fmask,
|
||||
int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
int *tmask, struct tm * tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
{
|
||||
int val;
|
||||
char *cp;
|
||||
@ -1389,12 +1382,12 @@ int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
if (*cp == '.')
|
||||
{
|
||||
/*
|
||||
* More than two digits? Then could be a date or a run-together
|
||||
* time: 2001.360 20011225 040506.789
|
||||
* More than two digits? Then could be a date or a run-together time:
|
||||
* 2001.360 20011225 040506.789
|
||||
*/
|
||||
if (cp - str > 2)
|
||||
return DecodeNumberField(flen, str, (fmask | DTK_DATE_M),
|
||||
tmask, tm, fsec, is2digits, EuroDates);
|
||||
tmask, tm, fsec, is2digits, EuroDates);
|
||||
|
||||
*fsec = strtod(cp, &cp);
|
||||
if (*cp != '\0')
|
||||
@ -1443,8 +1436,8 @@ int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
}
|
||||
/* no year and EuroDates enabled? then could be day */
|
||||
else if ((EuroDates || (fmask & DTK_M(MONTH))) &&
|
||||
!(fmask & DTK_M(YEAR)) && !(fmask & DTK_M(DAY)) &&
|
||||
val >= 1 && val <= 31)
|
||||
!(fmask & DTK_M(YEAR)) && !(fmask & DTK_M(DAY)) &&
|
||||
val >= 1 && val <= 31)
|
||||
{
|
||||
*tmask = DTK_M(DAY);
|
||||
tm->tm_mday = val;
|
||||
@ -1461,8 +1454,8 @@ int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for 2 or 4 or more digits, but currently we reach here only
|
||||
* if two digits. - thomas 2000-03-28
|
||||
* Check for 2 or 4 or more digits, but currently we reach here only if
|
||||
* two digits. - thomas 2000-03-28
|
||||
*/
|
||||
else if (!(fmask & DTK_M(YEAR)) && (flen >= 4 || flen == 2))
|
||||
{
|
||||
@ -1483,7 +1476,7 @@ int *tmask, struct tm *tm, fsec_t *fsec, int *is2digits, bool EuroDates)
|
||||
* Insist on a complete set of fields.
|
||||
*/
|
||||
static int
|
||||
DecodeDate(char *str, int fmask, int *tmask, struct tm *tm, bool EuroDates)
|
||||
DecodeDate(char *str, int fmask, int *tmask, struct tm * tm, bool EuroDates)
|
||||
{
|
||||
fsec_t fsec;
|
||||
|
||||
@ -1612,7 +1605,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm *tm, bool EuroDates)
|
||||
* can be used to represent time spans.
|
||||
*/
|
||||
static int
|
||||
DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec)
|
||||
DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
@ -1642,9 +1635,8 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec)
|
||||
char fstr[MAXDATELEN + 1];
|
||||
|
||||
/*
|
||||
* OK, we have at most six digits to work with. Let's
|
||||
* construct a string and then do the conversion to an
|
||||
* integer.
|
||||
* OK, we have at most six digits to work with. Let's construct a
|
||||
* string and then do the conversion to an integer.
|
||||
*/
|
||||
strncpy(fstr, (cp + 1), 7);
|
||||
strcpy(fstr + strlen(fstr), "000000");
|
||||
@ -1777,7 +1769,7 @@ DecodePosixTimezone(char *str, int *tzp)
|
||||
*/
|
||||
int
|
||||
ParseDateTime(char *timestr, char *lowstr,
|
||||
char **field, int *ftype, int maxfields, int *numfields, char **endstr)
|
||||
char **field, int *ftype, int maxfields, int *numfields, char **endstr)
|
||||
{
|
||||
int nf = 0;
|
||||
char *lp = lowstr;
|
||||
@ -1819,8 +1811,8 @@ ParseDateTime(char *timestr, char *lowstr,
|
||||
*lp++ = *(*endstr)++;
|
||||
|
||||
/*
|
||||
* insist that the delimiters match to get a
|
||||
* three-field date.
|
||||
* insist that the delimiters match to get a three-field
|
||||
* date.
|
||||
*/
|
||||
if (*(*endstr) == *dp)
|
||||
{
|
||||
@ -1839,8 +1831,8 @@ ParseDateTime(char *timestr, char *lowstr,
|
||||
}
|
||||
|
||||
/*
|
||||
* otherwise, number only and will determine year, month, day,
|
||||
* or concatenated fields later...
|
||||
* otherwise, number only and will determine year, month, day, or
|
||||
* concatenated fields later...
|
||||
*/
|
||||
else
|
||||
ftype[nf] = DTK_NUMBER;
|
||||
@ -1856,8 +1848,7 @@ ParseDateTime(char *timestr, char *lowstr,
|
||||
}
|
||||
|
||||
/*
|
||||
* text? then date string, month, day of week, special, or
|
||||
* timezone
|
||||
* text? then date string, month, day of week, special, or timezone
|
||||
*/
|
||||
else if (isalpha((unsigned char) *(*endstr)))
|
||||
{
|
||||
@ -1867,8 +1858,8 @@ ParseDateTime(char *timestr, char *lowstr,
|
||||
*lp++ = pg_tolower((unsigned char) *(*endstr)++);
|
||||
|
||||
/*
|
||||
* Full date string with leading text month? Could also be a
|
||||
* POSIX time zone...
|
||||
* Full date string with leading text month? Could also be a POSIX
|
||||
* time zone...
|
||||
*/
|
||||
if (*(*endstr) == '-' || *(*endstr) == '/' || *(*endstr) == '.')
|
||||
{
|
||||
@ -1960,13 +1951,12 @@ ParseDateTime(char *timestr, char *lowstr,
|
||||
*/
|
||||
int
|
||||
DecodeDateTime(char **field, int *ftype, int nf,
|
||||
int *dtype, struct tm *tm, fsec_t *fsec, int *tzp, bool EuroDates)
|
||||
int *dtype, struct tm * tm, fsec_t *fsec, int *tzp, bool EuroDates)
|
||||
{
|
||||
int fmask = 0,
|
||||
tmask,
|
||||
type;
|
||||
int ptype = 0; /* "prefix type" for ISO y2001m02d04
|
||||
* format */
|
||||
int ptype = 0; /* "prefix type" for ISO y2001m02d04 format */
|
||||
int i;
|
||||
int val;
|
||||
int mer = HR24;
|
||||
@ -2046,8 +2036,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
|
||||
/*
|
||||
* Starts with a digit but we already have a time
|
||||
* field? Then we are in trouble with a date and
|
||||
* time already...
|
||||
* field? Then we are in trouble with a date and time
|
||||
* already...
|
||||
*/
|
||||
if ((fmask & DTK_TIME_M) == DTK_TIME_M)
|
||||
return -1;
|
||||
@ -2061,11 +2051,11 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
* Then read the rest of the field as a
|
||||
* concatenated time
|
||||
* Then read the rest of the field as a concatenated
|
||||
* time
|
||||
*/
|
||||
if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], fmask,
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
@ -2096,8 +2086,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
* DecodeTime()
|
||||
*/
|
||||
/* test for > 24:00:00 */
|
||||
if (tm->tm_hour > 24 ||
|
||||
(tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0)))
|
||||
if (tm->tm_hour > 24 ||
|
||||
(tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0)))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
@ -2112,9 +2102,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Already have a time zone? Then maybe this is the
|
||||
* second field of a POSIX time: EST+3 (equivalent to
|
||||
* PST)
|
||||
* Already have a time zone? Then maybe this is the second
|
||||
* field of a POSIX time: EST+3 (equivalent to PST)
|
||||
*/
|
||||
if (i > 0 && (fmask & DTK_M(TZ)) != 0 &&
|
||||
ftype[i - 1] == DTK_TZ &&
|
||||
@ -2254,7 +2243,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
case DTK_TIME:
|
||||
/* previous field was "t" for ISO time */
|
||||
if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], (fmask | DTK_DATE_M),
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
return -1;
|
||||
|
||||
if (tmask != DTK_TIME_M)
|
||||
@ -2287,23 +2276,23 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
else if (cp != NULL && flen - strlen(cp) > 2)
|
||||
{
|
||||
/*
|
||||
* Interpret as a concatenated date or time Set
|
||||
* the type field to allow decoding other fields
|
||||
* later. Example: 20011223 or 040506
|
||||
* Interpret as a concatenated date or time Set the
|
||||
* type field to allow decoding other fields later.
|
||||
* Example: 20011223 or 040506
|
||||
*/
|
||||
if ((ftype[i] = DecodeNumberField(flen, field[i], fmask,
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
return -1;
|
||||
}
|
||||
else if (flen > 4)
|
||||
{
|
||||
if ((ftype[i] = DecodeNumberField(flen, field[i], fmask,
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
&tmask, tm, fsec, &is2digits, EuroDates)) < 0)
|
||||
return -1;
|
||||
}
|
||||
/* otherwise it is a single date/time field... */
|
||||
else if (DecodeNumber(flen, field[i], fmask,
|
||||
&tmask, tm, fsec, &is2digits, EuroDates) != 0)
|
||||
&tmask, tm, fsec, &is2digits, EuroDates) != 0)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@ -2376,8 +2365,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
case MONTH:
|
||||
|
||||
/*
|
||||
* already have a (numeric) month? then see if we
|
||||
* can substitute...
|
||||
* already have a (numeric) month? then see if we can
|
||||
* substitute...
|
||||
*/
|
||||
if ((fmask & DTK_M(MONTH)) && !haveTextMonth &&
|
||||
!(fmask & DTK_M(DAY)) && tm->tm_mon >= 1 && tm->tm_mon <= 31)
|
||||
@ -2392,8 +2381,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
case DTZMOD:
|
||||
|
||||
/*
|
||||
* daylight savings time modifier (solves "MET
|
||||
* DST" syntax)
|
||||
* daylight savings time modifier (solves "MET DST"
|
||||
* syntax)
|
||||
*/
|
||||
tmask |= DTK_M(DTZ);
|
||||
tm->tm_isdst = 1;
|
||||
@ -2405,8 +2394,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
case DTZ:
|
||||
|
||||
/*
|
||||
* set mask for TZ here _or_ check for DTZ later
|
||||
* when getting default timezone
|
||||
* set mask for TZ here _or_ check for DTZ later when
|
||||
* getting default timezone
|
||||
*/
|
||||
tmask |= DTK_M(TZ);
|
||||
tm->tm_isdst = 1;
|
||||
@ -2447,9 +2436,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
case ISOTIME:
|
||||
|
||||
/*
|
||||
* This is a filler field "t" indicating that the
|
||||
* next field is time. Try to verify that this is
|
||||
* sensible.
|
||||
* This is a filler field "t" indicating that the next
|
||||
* field is time. Try to verify that this is sensible.
|
||||
*/
|
||||
tmask = 0;
|
||||
|
||||
@ -2465,8 +2453,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
***/
|
||||
if (i >= nf - 1 ||
|
||||
(ftype[i + 1] != DTK_NUMBER &&
|
||||
ftype[i + 1] != DTK_TIME &&
|
||||
ftype[i + 1] != DTK_DATE))
|
||||
ftype[i + 1] != DTK_TIME &&
|
||||
ftype[i + 1] != DTK_DATE))
|
||||
return -1;
|
||||
|
||||
ptype = val;
|
||||
@ -2516,8 +2504,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
return ((fmask & DTK_TIME_M) == DTK_TIME_M) ? 1 : -1;
|
||||
|
||||
/*
|
||||
* check for valid day of month, now that we know for sure the
|
||||
* month and year...
|
||||
* check for valid day of month, now that we know for sure the month
|
||||
* and year...
|
||||
*/
|
||||
if (tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
||||
return -1;
|
||||
@ -2526,8 +2514,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
if ((fmask & DTK_DATE_M) == DTK_DATE_M && tzp != NULL && !(fmask & DTK_M(TZ)))
|
||||
{
|
||||
/*
|
||||
* daylight savings time modifier but no standard timezone?
|
||||
* then error
|
||||
* daylight savings time modifier but no standard timezone? then
|
||||
* error
|
||||
*/
|
||||
if (fmask & DTK_M(DTZMOD))
|
||||
return -1;
|
||||
@ -2554,14 +2542,12 @@ find_end_token(char *str, char *fmt)
|
||||
* functions gets called as find_end_token("28the day12the hour", "the
|
||||
* day%hthehour")
|
||||
*
|
||||
* fmt points to "the day%hthehour", next_percent points to %hthehour and
|
||||
* we have to find a match for everything between these positions
|
||||
* ("the day"). We look for "the day" in str and know that the pattern
|
||||
* we are about to scan ends where this string starts (right after the
|
||||
* "28")
|
||||
* fmt points to "the day%hthehour", next_percent points to %hthehour and we
|
||||
* have to find a match for everything between these positions ("the
|
||||
* day"). We look for "the day" in str and know that the pattern we are
|
||||
* about to scan ends where this string starts (right after the "28")
|
||||
*
|
||||
* At the end, *fmt is '\0' and *str isn't. end_position then is
|
||||
* unchanged.
|
||||
* At the end, *fmt is '\0' and *str isn't. end_position then is unchanged.
|
||||
*/
|
||||
char *end_position = NULL;
|
||||
char *next_percent,
|
||||
@ -2580,10 +2566,10 @@ find_end_token(char *str, char *fmt)
|
||||
while (fmt[scan_offset] == '%' && fmt[scan_offset + 1])
|
||||
{
|
||||
/*
|
||||
* there is no delimiter, skip to the next delimiter if we're
|
||||
* reading a number and then something that is not a number
|
||||
* "9:15pm", we might be able to recover with the strtol end
|
||||
* pointer. Go for the next percent sign
|
||||
* there is no delimiter, skip to the next delimiter if we're reading
|
||||
* a number and then something that is not a number "9:15pm", we might
|
||||
* be able to recover with the strtol end pointer. Go for the next
|
||||
* percent sign
|
||||
*/
|
||||
scan_offset += 2;
|
||||
}
|
||||
@ -2591,10 +2577,10 @@ find_end_token(char *str, char *fmt)
|
||||
if (next_percent)
|
||||
{
|
||||
/*
|
||||
* we don't want to allocate extra memory, so we temporarily set
|
||||
* the '%' sign to '\0' and call strstr However since we allow
|
||||
* whitespace to float around everything, we have to shorten the
|
||||
* pattern until we reach a non-whitespace character
|
||||
* we don't want to allocate extra memory, so we temporarily set the
|
||||
* '%' sign to '\0' and call strstr However since we allow whitespace
|
||||
* to float around everything, we have to shorten the pattern until we
|
||||
* reach a non-whitespace character
|
||||
*/
|
||||
|
||||
subst_location = next_percent;
|
||||
@ -2604,16 +2590,16 @@ find_end_token(char *str, char *fmt)
|
||||
*subst_location = '\0';
|
||||
|
||||
/*
|
||||
* the haystack is the str and the needle is the original fmt but
|
||||
* it ends at the position where the next percent sign would be
|
||||
* the haystack is the str and the needle is the original fmt but it
|
||||
* ends at the position where the next percent sign would be
|
||||
*/
|
||||
|
||||
/*
|
||||
* There is one special case. Imagine: str = " 2", fmt = "%d
|
||||
* %...", since we want to allow blanks as "dynamic" padding we
|
||||
* have to accept this. Now, we are called with a fmt of " %..."
|
||||
* and look for " " in str. We find it at the first position and
|
||||
* never read the 2...
|
||||
* There is one special case. Imagine: str = " 2", fmt = "%d %...",
|
||||
* since we want to allow blanks as "dynamic" padding we have to
|
||||
* accept this. Now, we are called with a fmt of " %..." and look for
|
||||
* " " in str. We find it at the first position and never read the
|
||||
* 2...
|
||||
*/
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
@ -2623,8 +2609,8 @@ find_end_token(char *str, char *fmt)
|
||||
else
|
||||
{
|
||||
/*
|
||||
* there is no other percent sign. So everything up to the end has
|
||||
* to match.
|
||||
* there is no other percent sign. So everything up to the end has to
|
||||
* match.
|
||||
*/
|
||||
end_position = str + strlen(str);
|
||||
}
|
||||
@ -2641,8 +2627,8 @@ find_end_token(char *str, char *fmt)
|
||||
*
|
||||
* and have set fmt to " " because overwrote the % sign with a NULL
|
||||
*
|
||||
* In this case where we would have to match a space but can't find
|
||||
* it, set end_position to the end of the string
|
||||
* In this case where we would have to match a space but can't find it,
|
||||
* set end_position to the end of the string
|
||||
*/
|
||||
if ((fmt + scan_offset)[0] == ' ' && fmt + scan_offset + 1 == subst_location)
|
||||
end_position = str + strlen(str);
|
||||
@ -2654,8 +2640,8 @@ static int
|
||||
pgtypes_defmt_scan(union un_fmt_comb * scan_val, int scan_type, char **pstr, char *pfmt)
|
||||
{
|
||||
/*
|
||||
* scan everything between pstr and pstr_end. This is not including
|
||||
* the last character so we might set it to '\0' for the parsing
|
||||
* scan everything between pstr and pstr_end. This is not including the
|
||||
* last character so we might set it to '\0' for the parsing
|
||||
*/
|
||||
|
||||
char last_char;
|
||||
@ -2679,8 +2665,8 @@ pgtypes_defmt_scan(union un_fmt_comb * scan_val, int scan_type, char **pstr, cha
|
||||
case PGTYPES_TYPE_UINT:
|
||||
|
||||
/*
|
||||
* numbers may be blank-padded, this is the only deviation
|
||||
* from the fmt-string we accept
|
||||
* numbers may be blank-padded, this is the only deviation from
|
||||
* the fmt-string we accept
|
||||
*/
|
||||
while (**pstr == ' ')
|
||||
(*pstr)++;
|
||||
@ -2716,7 +2702,7 @@ int PGTYPEStimestamp_defmt_scan(char **, char *, timestamp *, int *, int *, int
|
||||
int *, int *, int *, int *);
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
|
||||
int *year, int *month, int *day,
|
||||
int *hour, int *minute, int *second,
|
||||
int *tz)
|
||||
@ -2764,15 +2750,15 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
pfmt++;
|
||||
|
||||
/*
|
||||
* we parse the day and see if it is a week day but we do
|
||||
* not check if the week day really matches the date
|
||||
* we parse the day and see if it is a week day but we do not
|
||||
* check if the week day really matches the date
|
||||
*/
|
||||
err = 1;
|
||||
j = 0;
|
||||
while (pgtypes_date_weekdays_short[j])
|
||||
{
|
||||
if (strncmp(pgtypes_date_weekdays_short[j], pstr,
|
||||
strlen(pgtypes_date_weekdays_short[j])) == 0)
|
||||
strlen(pgtypes_date_weekdays_short[j])) == 0)
|
||||
{
|
||||
/* found it */
|
||||
err = 0;
|
||||
@ -2854,8 +2840,8 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
case 'D':
|
||||
|
||||
/*
|
||||
* we have to concatenate the strings in order to be able
|
||||
* to find the end of the substitution
|
||||
* we have to concatenate the strings in order to be able to
|
||||
* find the end of the substitution
|
||||
*/
|
||||
pfmt++;
|
||||
tmp = pgtypes_alloc(strlen("%m/%d/%y") + strlen(pstr) + 1);
|
||||
@ -2908,8 +2894,8 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
|
||||
/*
|
||||
* XXX what should we do with that? We could say that it's
|
||||
* sufficient if we have the year and the day within the
|
||||
* year to get at least a specific day.
|
||||
* sufficient if we have the year and the day within the year
|
||||
* to get at least a specific day.
|
||||
*/
|
||||
break;
|
||||
case 'M':
|
||||
@ -3097,8 +3083,8 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
|
||||
|
||||
/*
|
||||
* XXX use DecodeSpecial instead ? - it's declared static
|
||||
* but the arrays as well. :-(
|
||||
* XXX use DecodeSpecial instead ? - it's declared static but
|
||||
* the arrays as well. :-(
|
||||
*/
|
||||
for (j = 0; !err && j < szdatetktbl; j++)
|
||||
{
|
||||
@ -3106,8 +3092,8 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
{
|
||||
/*
|
||||
* tz calculates the offset for the seconds, the
|
||||
* timezone value of the datetktbl table is in
|
||||
* quarter hours
|
||||
* timezone value of the datetktbl table is in quarter
|
||||
* hours
|
||||
*/
|
||||
*tz = -15 * MINS_PER_HOUR * datetktbl[j].value;
|
||||
break;
|
||||
@ -3163,7 +3149,7 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
|
||||
err = 1;
|
||||
*minute = 0;
|
||||
}
|
||||
if (*hour > 24 || /* test for > 24:00:00 */
|
||||
if (*hour > 24 || /* test for > 24:00:00 */
|
||||
(*hour == 24 && (*minute > 0 || *second > 0)))
|
||||
{
|
||||
err = 1;
|
||||
|
@ -12,10 +12,10 @@
|
||||
#define PGTYPES_TYPE_DOUBLE_NF 4 /* no fractional part */
|
||||
#define PGTYPES_TYPE_INT64 5
|
||||
#define PGTYPES_TYPE_UINT 6
|
||||
#define PGTYPES_TYPE_UINT_2_LZ 7 /* 2 digits, pad with
|
||||
* leading zero */
|
||||
#define PGTYPES_TYPE_UINT_2_LS 8 /* 2 digits, pad with
|
||||
* leading space */
|
||||
#define PGTYPES_TYPE_UINT_2_LZ 7 /* 2 digits, pad with leading
|
||||
* zero */
|
||||
#define PGTYPES_TYPE_UINT_2_LS 8 /* 2 digits, pad with leading
|
||||
* space */
|
||||
#define PGTYPES_TYPE_UINT_3_LZ 9
|
||||
#define PGTYPES_TYPE_UINT_4_LZ 10
|
||||
#define PGTYPES_TYPE_UINT_LONG 11
|
||||
|
@ -33,7 +33,7 @@ TrimTrailingZeros(char *str)
|
||||
* can be used to represent time spans.
|
||||
*/
|
||||
static int
|
||||
DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec)
|
||||
DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
@ -63,9 +63,8 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec)
|
||||
char fstr[MAXDATELEN + 1];
|
||||
|
||||
/*
|
||||
* OK, we have at most six digits to work with. Let's
|
||||
* construct a string and then do the conversion to an
|
||||
* integer.
|
||||
* OK, we have at most six digits to work with. Let's construct a
|
||||
* string and then do the conversion to an integer.
|
||||
*/
|
||||
strncpy(fstr, (cp + 1), 7);
|
||||
strcpy(fstr + strlen(fstr), "000000");
|
||||
@ -107,7 +106,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, fsec_t *fsec)
|
||||
* preceding an hh:mm:ss field. - thomas 1998-04-30
|
||||
*/
|
||||
int
|
||||
DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm *tm, fsec_t *fsec)
|
||||
DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fsec_t *fsec)
|
||||
{
|
||||
int is_before = FALSE;
|
||||
|
||||
@ -149,9 +148,9 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm *tm, fsec
|
||||
*/
|
||||
|
||||
/*
|
||||
* A single signed number ends up here, but will be
|
||||
* rejected by DecodeTime(). So, work this out to drop
|
||||
* through to DTK_NUMBER, which *can* tolerate this.
|
||||
* A single signed number ends up here, but will be rejected
|
||||
* by DecodeTime(). So, work this out to drop through to
|
||||
* DTK_NUMBER, which *can* tolerate this.
|
||||
*/
|
||||
cp = field[i] + 1;
|
||||
while (*cp != '\0' && *cp != ':' && *cp != '.')
|
||||
@ -169,8 +168,8 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm *tm, fsec
|
||||
|
||||
/*
|
||||
* Set the next type to be a day, if units are not
|
||||
* specified. This handles the case of '1 +02:03'
|
||||
* since we are reading right to left.
|
||||
* specified. This handles the case of '1 +02:03' since we
|
||||
* are reading right to left.
|
||||
*/
|
||||
type = DTK_DAY;
|
||||
tmask = DTK_M(TZ);
|
||||
@ -445,7 +444,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm *tm, fsec
|
||||
* - thomas 1998-04-30
|
||||
*/
|
||||
int
|
||||
EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str)
|
||||
EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str)
|
||||
{
|
||||
int is_before = FALSE;
|
||||
int is_nonzero = FALSE;
|
||||
@ -453,9 +452,8 @@ EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str)
|
||||
|
||||
/*
|
||||
* The sign of year and month are guaranteed to match, since they are
|
||||
* stored internally as "month". But we'll need to check for is_before
|
||||
* and is_nonzero when determining the signs of hour/minute/seconds
|
||||
* fields.
|
||||
* stored internally as "month". But we'll need to check for is_before and
|
||||
* is_nonzero when determining the signs of hour/minute/seconds fields.
|
||||
*/
|
||||
switch (style)
|
||||
{
|
||||
@ -493,7 +491,7 @@ EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str)
|
||||
tm->tm_sec != 0 || fsec != 0)
|
||||
{
|
||||
int minus = tm->tm_hour < 0 || tm->tm_min < 0 ||
|
||||
tm->tm_sec < 0 || fsec < 0;
|
||||
tm->tm_sec < 0 || fsec < 0;
|
||||
|
||||
sprintf(cp, "%s%s%02d:%02d", (is_nonzero ? " " : ""),
|
||||
(minus ? "-" : (is_before ? "+" : "")),
|
||||
@ -511,7 +509,7 @@ EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str)
|
||||
sprintf(cp, ".%06d", Abs(fsec));
|
||||
#else
|
||||
fsec += tm->tm_sec;
|
||||
sprintf(cp, ":%012.9f", fabs(fsec));
|
||||
sprintf(cp, ":%012.9f", fabs(fsec));
|
||||
#endif
|
||||
TrimTrailingZeros(cp);
|
||||
cp += strlen(cp);
|
||||
@ -670,7 +668,7 @@ EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str)
|
||||
* Convert a interval data type to a tm structure.
|
||||
*/
|
||||
static int
|
||||
interval2tm(interval span, struct tm *tm, fsec_t *fsec)
|
||||
interval2tm(interval span, struct tm * tm, fsec_t *fsec)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int64 time;
|
||||
@ -703,9 +701,9 @@ interval2tm(interval span, struct tm *tm, fsec_t *fsec)
|
||||
*fsec = time - (tm->tm_sec * USECS_PER_SEC);
|
||||
#else
|
||||
recalc:
|
||||
TMODULO(time, tm->tm_mday, (double)SECS_PER_DAY);
|
||||
TMODULO(time, tm->tm_hour, (double)SECS_PER_HOUR);
|
||||
TMODULO(time, tm->tm_min, (double)SECS_PER_MINUTE);
|
||||
TMODULO(time, tm->tm_mday, (double) SECS_PER_DAY);
|
||||
TMODULO(time, tm->tm_hour, (double) SECS_PER_HOUR);
|
||||
TMODULO(time, tm->tm_min, (double) SECS_PER_MINUTE);
|
||||
TMODULO(time, tm->tm_sec, 1.0);
|
||||
time = TSROUND(time);
|
||||
/* roundoff may need to propagate to higher-order fields */
|
||||
@ -721,19 +719,19 @@ recalc:
|
||||
} /* interval2tm() */
|
||||
|
||||
static int
|
||||
tm2interval(struct tm *tm, fsec_t fsec, interval *span)
|
||||
tm2interval(struct tm * tm, fsec_t fsec, interval * span)
|
||||
{
|
||||
span->month = tm->tm_year * MONTHS_PER_YEAR + tm->tm_mon;
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
span->time = (((((((tm->tm_mday * INT64CONST(24)) +
|
||||
tm->tm_hour) * INT64CONST(60)) +
|
||||
tm->tm_min) * INT64CONST(60)) +
|
||||
tm->tm_sec) * USECS_PER_SEC) + fsec;
|
||||
tm->tm_hour) * INT64CONST(60)) +
|
||||
tm->tm_min) * INT64CONST(60)) +
|
||||
tm->tm_sec) * USECS_PER_SEC) + fsec;
|
||||
#else
|
||||
span->time = (((((tm->tm_mday * (double)HOURS_PER_DAY) +
|
||||
tm->tm_hour) * (double)MINS_PER_HOUR) +
|
||||
tm->tm_min) * (double)SECS_PER_MINUTE) +
|
||||
tm->tm_sec + fsec;
|
||||
span->time = (((((tm->tm_mday * (double) HOURS_PER_DAY) +
|
||||
tm->tm_hour) * (double) MINS_PER_HOUR) +
|
||||
tm->tm_min) * (double) SECS_PER_MINUTE) +
|
||||
tm->tm_sec + fsec;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -797,7 +795,7 @@ PGTYPESinterval_from_asc(char *str, char **endptr)
|
||||
}
|
||||
|
||||
char *
|
||||
PGTYPESinterval_to_asc(interval *span)
|
||||
PGTYPESinterval_to_asc(interval * span)
|
||||
{
|
||||
struct tm tt,
|
||||
*tm = &tt;
|
||||
@ -821,7 +819,7 @@ PGTYPESinterval_to_asc(interval *span)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESinterval_copy(interval *intvlsrc, interval *intrcldest)
|
||||
PGTYPESinterval_copy(interval * intvlsrc, interval * intrcldest)
|
||||
{
|
||||
intrcldest->time = intvlsrc->time;
|
||||
intrcldest->month = intvlsrc->month;
|
||||
|
@ -28,7 +28,7 @@
|
||||
* ----------
|
||||
*/
|
||||
static int
|
||||
apply_typmod(numeric *var, long typmod)
|
||||
apply_typmod(numeric * var, long typmod)
|
||||
{
|
||||
int precision;
|
||||
int scale;
|
||||
@ -71,10 +71,10 @@ apply_typmod(numeric *var, long typmod)
|
||||
|
||||
/*
|
||||
* Check for overflow - note we can't do this before rounding, because
|
||||
* rounding could raise the weight. Also note that the var's weight
|
||||
* could be inflated by leading zeroes, which will be stripped before
|
||||
* storage but perhaps might not have been yet. In any case, we must
|
||||
* recognize a true zero, whose weight doesn't mean anything.
|
||||
* rounding could raise the weight. Also note that the var's weight could
|
||||
* be inflated by leading zeroes, which will be stripped before storage
|
||||
* but perhaps might not have been yet. In any case, we must recognize a
|
||||
* true zero, whose weight doesn't mean anything.
|
||||
*/
|
||||
if (var->weight >= maxweight)
|
||||
{
|
||||
@ -108,7 +108,7 @@ apply_typmod(numeric *var, long typmod)
|
||||
* ----------
|
||||
*/
|
||||
static int
|
||||
alloc_var(numeric *var, int ndigits)
|
||||
alloc_var(numeric * var, int ndigits)
|
||||
{
|
||||
digitbuf_free(var->buf);
|
||||
var->buf = digitbuf_alloc(ndigits + 1);
|
||||
@ -141,7 +141,7 @@ PGTYPESnumeric_new(void)
|
||||
* ----------
|
||||
*/
|
||||
static int
|
||||
set_var_from_str(char *str, char **ptr, numeric *dest)
|
||||
set_var_from_str(char *str, char **ptr, numeric * dest)
|
||||
{
|
||||
bool have_dp = FALSE;
|
||||
int i = 0;
|
||||
@ -271,7 +271,7 @@ set_var_from_str(char *str, char **ptr, numeric *dest)
|
||||
* ----------
|
||||
*/
|
||||
static char *
|
||||
get_str_from_var(numeric *var, int dscale)
|
||||
get_str_from_var(numeric * var, int dscale)
|
||||
{
|
||||
char *str;
|
||||
char *cp;
|
||||
@ -334,8 +334,7 @@ get_str_from_var(numeric *var, int dscale)
|
||||
}
|
||||
|
||||
/*
|
||||
* If requested, output a decimal point and all the digits that follow
|
||||
* it.
|
||||
* If requested, output a decimal point and all the digits that follow it.
|
||||
*/
|
||||
if (dscale > 0)
|
||||
{
|
||||
@ -385,7 +384,7 @@ PGTYPESnumeric_from_asc(char *str, char **endptr)
|
||||
}
|
||||
|
||||
char *
|
||||
PGTYPESnumeric_to_asc(numeric *num, int dscale)
|
||||
PGTYPESnumeric_to_asc(numeric * num, int dscale)
|
||||
{
|
||||
if (dscale < 0)
|
||||
dscale = num->dscale;
|
||||
@ -401,7 +400,7 @@ PGTYPESnumeric_to_asc(numeric *num, int dscale)
|
||||
* ----------
|
||||
*/
|
||||
static void
|
||||
zero_var(numeric *var)
|
||||
zero_var(numeric * var)
|
||||
{
|
||||
digitbuf_free(var->buf);
|
||||
var->buf = NULL;
|
||||
@ -412,7 +411,7 @@ zero_var(numeric *var)
|
||||
}
|
||||
|
||||
void
|
||||
PGTYPESnumeric_free(numeric *var)
|
||||
PGTYPESnumeric_free(numeric * var)
|
||||
{
|
||||
digitbuf_free(var->buf);
|
||||
free(var);
|
||||
@ -428,7 +427,7 @@ PGTYPESnumeric_free(numeric *var)
|
||||
* ----------
|
||||
*/
|
||||
static int
|
||||
cmp_abs(numeric *var1, numeric *var2)
|
||||
cmp_abs(numeric * var1, numeric * var2)
|
||||
{
|
||||
int i1 = 0;
|
||||
int i2 = 0;
|
||||
@ -486,7 +485,7 @@ cmp_abs(numeric *var1, numeric *var2)
|
||||
* ----------
|
||||
*/
|
||||
static int
|
||||
add_abs(numeric *var1, numeric *var2, numeric *result)
|
||||
add_abs(numeric * var1, numeric * var2, numeric * result)
|
||||
{
|
||||
NumericDigit *res_buf;
|
||||
NumericDigit *res_digits;
|
||||
@ -574,7 +573,7 @@ add_abs(numeric *var1, numeric *var2, numeric *result)
|
||||
* ----------
|
||||
*/
|
||||
static int
|
||||
sub_abs(numeric *var1, numeric *var2, numeric *result)
|
||||
sub_abs(numeric * var1, numeric * var2, numeric * result)
|
||||
{
|
||||
NumericDigit *res_buf;
|
||||
NumericDigit *res_digits;
|
||||
@ -658,7 +657,7 @@ sub_abs(numeric *var1, numeric *var2, numeric *result)
|
||||
* ----------
|
||||
*/
|
||||
int
|
||||
PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result)
|
||||
PGTYPESnumeric_add(numeric * var1, numeric * var2, numeric * result)
|
||||
{
|
||||
/*
|
||||
* Decide on the signs of the two variables what to do
|
||||
@ -677,8 +676,7 @@ PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result)
|
||||
else
|
||||
{
|
||||
/*
|
||||
* var1 is positive, var2 is negative Must compare absolute
|
||||
* values
|
||||
* var1 is positive, var2 is negative Must compare absolute values
|
||||
*/
|
||||
switch (cmp_abs(var1, var2))
|
||||
{
|
||||
@ -787,7 +785,7 @@ PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result)
|
||||
* ----------
|
||||
*/
|
||||
int
|
||||
PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result)
|
||||
PGTYPESnumeric_sub(numeric * var1, numeric * var2, numeric * result)
|
||||
{
|
||||
/*
|
||||
* Decide on the signs of the two variables what to do
|
||||
@ -918,7 +916,7 @@ PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result)
|
||||
* ----------
|
||||
*/
|
||||
int
|
||||
PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result)
|
||||
PGTYPESnumeric_mul(numeric * var1, numeric * var2, numeric * result)
|
||||
{
|
||||
NumericDigit *res_buf;
|
||||
NumericDigit *res_digits;
|
||||
@ -1009,7 +1007,7 @@ PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result)
|
||||
* Note that this must be called before div_var.
|
||||
*/
|
||||
static int
|
||||
select_div_scale(numeric *var1, numeric *var2, int *rscale)
|
||||
select_div_scale(numeric * var1, numeric * var2, int *rscale)
|
||||
{
|
||||
int weight1,
|
||||
weight2,
|
||||
@ -1021,8 +1019,8 @@ select_div_scale(numeric *var1, numeric *var2, int *rscale)
|
||||
int res_rscale;
|
||||
|
||||
/*
|
||||
* The result scale of a division isn't specified in any SQL standard.
|
||||
* For PostgreSQL we select a display scale that will give at least
|
||||
* The result scale of a division isn't specified in any SQL standard. For
|
||||
* PostgreSQL we select a display scale that will give at least
|
||||
* NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
|
||||
* result no less accurate than float8; but use a scale not less than
|
||||
* either input's display scale.
|
||||
@ -1076,7 +1074,7 @@ select_div_scale(numeric *var1, numeric *var2, int *rscale)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
|
||||
PGTYPESnumeric_div(numeric * var1, numeric * var2, numeric * result)
|
||||
{
|
||||
NumericDigit *res_digits;
|
||||
int res_ndigits;
|
||||
@ -1165,9 +1163,9 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
|
||||
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.
|
||||
* 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)
|
||||
@ -1284,9 +1282,10 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
|
||||
result->sign = NUMERIC_POS;
|
||||
|
||||
result->dscale = res_dscale;
|
||||
err = 0; /* if we've made it this far, return success */
|
||||
err = 0; /* if we've made it this far, return success */
|
||||
|
||||
done:
|
||||
|
||||
/*
|
||||
* Tidy up
|
||||
*/
|
||||
@ -1304,7 +1303,7 @@ done:
|
||||
|
||||
|
||||
int
|
||||
PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
|
||||
PGTYPESnumeric_cmp(numeric * var1, numeric * var2)
|
||||
{
|
||||
|
||||
/* use cmp_abs function to calculate the result */
|
||||
@ -1317,8 +1316,7 @@ PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
|
||||
if (var1->sign == NUMERIC_NEG && var2->sign == NUMERIC_NEG)
|
||||
{
|
||||
/*
|
||||
* instead of inverting the result, we invert the paramter
|
||||
* ordering
|
||||
* instead of inverting the result, we invert the paramter ordering
|
||||
*/
|
||||
return cmp_abs(var2, var1);
|
||||
}
|
||||
@ -1335,7 +1333,7 @@ PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_from_int(signed int int_val, numeric *var)
|
||||
PGTYPESnumeric_from_int(signed int int_val, numeric * var)
|
||||
{
|
||||
/* implicit conversion */
|
||||
signed long int long_int = int_val;
|
||||
@ -1344,14 +1342,14 @@ PGTYPESnumeric_from_int(signed int int_val, numeric *var)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_from_long(signed long int long_val, numeric *var)
|
||||
PGTYPESnumeric_from_long(signed long int long_val, numeric * var)
|
||||
{
|
||||
/* 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
|
||||
* however we multiply by 10 each time and compare instead of calculating
|
||||
* the logarithm
|
||||
*/
|
||||
|
||||
int size = 0;
|
||||
@ -1405,8 +1403,8 @@ PGTYPESnumeric_from_long(signed long int long_val, numeric *var)
|
||||
|
||||
/*
|
||||
* 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
|
||||
* initialized properly and filled with '0', so converting 10000 in
|
||||
* only one step is no problem
|
||||
*/
|
||||
} while (abs_long_val > 0);
|
||||
|
||||
@ -1414,7 +1412,7 @@ PGTYPESnumeric_from_long(signed long int long_val, numeric *var)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_copy(numeric *src, numeric *dst)
|
||||
PGTYPESnumeric_copy(numeric * src, numeric * dst)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1437,7 +1435,7 @@ PGTYPESnumeric_copy(numeric *src, numeric *dst)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_from_double(double d, numeric *dst)
|
||||
PGTYPESnumeric_from_double(double d, numeric * dst)
|
||||
{
|
||||
char buffer[100];
|
||||
numeric *tmp;
|
||||
@ -1454,7 +1452,7 @@ PGTYPESnumeric_from_double(double d, numeric *dst)
|
||||
}
|
||||
|
||||
static int
|
||||
numericvar_to_double_no_overflow(numeric *var, double *dp)
|
||||
numericvar_to_double_no_overflow(numeric * var, double *dp)
|
||||
{
|
||||
char *tmp;
|
||||
double val;
|
||||
@ -1478,7 +1476,7 @@ numericvar_to_double_no_overflow(numeric *var, double *dp)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_to_double(numeric *nv, double *dp)
|
||||
PGTYPESnumeric_to_double(numeric * nv, double *dp)
|
||||
{
|
||||
double tmp;
|
||||
int i;
|
||||
@ -1490,7 +1488,7 @@ PGTYPESnumeric_to_double(numeric *nv, double *dp)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_to_int(numeric *nv, int *ip)
|
||||
PGTYPESnumeric_to_int(numeric * nv, int *ip)
|
||||
{
|
||||
long l;
|
||||
int i;
|
||||
@ -1509,7 +1507,7 @@ PGTYPESnumeric_to_int(numeric *nv, int *ip)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_to_long(numeric *nv, long *lp)
|
||||
PGTYPESnumeric_to_long(numeric * nv, long *lp)
|
||||
{
|
||||
int i;
|
||||
long l = 0;
|
||||
@ -1537,7 +1535,7 @@ PGTYPESnumeric_to_long(numeric *nv, long *lp)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_to_decimal(numeric *src, decimal *dst)
|
||||
PGTYPESnumeric_to_decimal(numeric * src, decimal * dst)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1560,7 +1558,7 @@ PGTYPESnumeric_to_decimal(numeric *src, decimal *dst)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPESnumeric_from_decimal(decimal *src, numeric *dst)
|
||||
PGTYPESnumeric_from_decimal(decimal * src, numeric * dst)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -24,7 +24,6 @@ time2t(const int hour, const int min, const int sec, const fsec_t fsec)
|
||||
{
|
||||
return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
|
||||
} /* time2t() */
|
||||
|
||||
#else
|
||||
static double
|
||||
time2t(const int hour, const int min, const int sec, const fsec_t fsec)
|
||||
@ -52,12 +51,11 @@ dt2local(timestamp dt, int tz)
|
||||
* Returns -1 on failure (overflow).
|
||||
*/
|
||||
int
|
||||
tm2timestamp(struct tm *tm, fsec_t fsec, int *tzp, timestamp *result)
|
||||
tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, timestamp * result)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int dDate;
|
||||
int64 time;
|
||||
|
||||
#else
|
||||
double dDate,
|
||||
time;
|
||||
@ -141,7 +139,7 @@ dt2time(timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
|
||||
* local time zone. If out of this range, leave as GMT. - tgl 97/05/27
|
||||
*/
|
||||
static int
|
||||
timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, char **tzn)
|
||||
timestamp2tm(timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int64 dDate,
|
||||
@ -181,7 +179,7 @@ timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, char **tzn)
|
||||
dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
|
||||
#else
|
||||
time = dt;
|
||||
TMODULO(time, dDate, (double)SECS_PER_DAY);
|
||||
TMODULO(time, dDate, (double) SECS_PER_DAY);
|
||||
|
||||
if (time < 0)
|
||||
{
|
||||
@ -206,7 +204,7 @@ recalc_t:
|
||||
if (*fsec >= 1.0)
|
||||
{
|
||||
time = ceil(time);
|
||||
if (time >= (double)SECS_PER_DAY)
|
||||
if (time >= (double) SECS_PER_DAY)
|
||||
{
|
||||
time = 0;
|
||||
dDate += 1;
|
||||
@ -244,7 +242,7 @@ recalc_t:
|
||||
tm->tm_gmtoff = tx->tm_gmtoff;
|
||||
tm->tm_zone = tx->tm_zone;
|
||||
|
||||
*tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
|
||||
*tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
|
||||
if (tzn != NULL)
|
||||
*tzn = (char *) tm->tm_zone;
|
||||
#elif defined(HAVE_INT_TIMEZONE)
|
||||
@ -252,7 +250,6 @@ recalc_t:
|
||||
if (tzn != NULL)
|
||||
*tzn = TZNAME_GLOBAL[(tm->tm_isdst > 0)];
|
||||
#endif
|
||||
|
||||
#else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
|
||||
*tzp = 0;
|
||||
/* Mark this as *no* time zone available */
|
||||
@ -367,8 +364,8 @@ PGTYPEStimestamp_from_asc(char *str, char **endptr)
|
||||
/* AdjustTimestampForTypmod(&result, typmod); */
|
||||
|
||||
/*
|
||||
* Since it's difficult to test for noresult, make sure errno is 0 if
|
||||
* no error occured.
|
||||
* Since it's difficult to test for noresult, make sure errno is 0 if no
|
||||
* error occured.
|
||||
*/
|
||||
errno = 0;
|
||||
return result;
|
||||
@ -382,8 +379,8 @@ PGTYPEStimestamp_to_asc(timestamp tstamp)
|
||||
char buf[MAXDATELEN + 1];
|
||||
char *tzn = NULL;
|
||||
fsec_t fsec;
|
||||
int DateStyle = 1; /* this defaults to ISO_DATES, shall we
|
||||
* make it an option? */
|
||||
int DateStyle = 1; /* this defaults to ISO_DATES, shall we make
|
||||
* it an option? */
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(tstamp))
|
||||
EncodeSpecialTimestamp(tstamp, buf);
|
||||
@ -398,7 +395,7 @@ PGTYPEStimestamp_to_asc(timestamp tstamp)
|
||||
}
|
||||
|
||||
void
|
||||
PGTYPEStimestamp_current(timestamp *ts)
|
||||
PGTYPEStimestamp_current(timestamp * ts)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
@ -408,7 +405,7 @@ PGTYPEStimestamp_current(timestamp *ts)
|
||||
}
|
||||
|
||||
static int
|
||||
dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm,
|
||||
dttofmtasc_replace(timestamp * ts, date dDate, int dow, struct tm * tm,
|
||||
char *output, int *pstr_len, char *fmtstr)
|
||||
{
|
||||
union un_fmt_comb replace_val;
|
||||
@ -457,8 +454,7 @@ dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm,
|
||||
case 'D':
|
||||
|
||||
/*
|
||||
* ts, dDate, dow, tm is information about the
|
||||
* timestamp
|
||||
* ts, dDate, dow, tm is information about the timestamp
|
||||
*
|
||||
* q is the start of the current output buffer
|
||||
*
|
||||
@ -518,8 +514,8 @@ dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm,
|
||||
case 'g':
|
||||
/* XXX: fall back to strftime */
|
||||
{
|
||||
char *fmt = "%g"; /* Keep compiler quiet
|
||||
* about 2-digit year */
|
||||
char *fmt = "%g"; /* Keep compiler quiet about
|
||||
* 2-digit year */
|
||||
|
||||
tm->tm_mon -= 1;
|
||||
i = strftime(q, *pstr_len, fmt, tm);
|
||||
@ -671,8 +667,8 @@ dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm,
|
||||
case 'x':
|
||||
/* XXX: fall back to strftime */
|
||||
{
|
||||
char *fmt = "%x"; /* Keep compiler quiet
|
||||
* about 2-digit year */
|
||||
char *fmt = "%x"; /* Keep compiler quiet about
|
||||
* 2-digit year */
|
||||
|
||||
tm->tm_mon -= 1;
|
||||
i = strftime(q, *pstr_len, fmt, tm);
|
||||
@ -798,7 +794,7 @@ dttofmtasc_replace(timestamp *ts, date dDate, int dow, struct tm *tm,
|
||||
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr)
|
||||
PGTYPEStimestamp_fmt_asc(timestamp * ts, char *output, int str_len, char *fmtstr)
|
||||
{
|
||||
struct tm tm;
|
||||
fsec_t fsec;
|
||||
@ -813,7 +809,7 @@ PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv)
|
||||
PGTYPEStimestamp_sub(timestamp * ts1, timestamp * ts2, interval * iv)
|
||||
{
|
||||
if (TIMESTAMP_NOT_FINITE(*ts1) || TIMESTAMP_NOT_FINITE(*ts2))
|
||||
return PGTYPES_TS_ERR_EINFTIME;
|
||||
@ -826,7 +822,7 @@ PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv)
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d)
|
||||
PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp * d)
|
||||
{
|
||||
int year,
|
||||
month,
|
||||
@ -870,83 +866,82 @@ PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d)
|
||||
/*
|
||||
* add an interval to a time stamp
|
||||
*
|
||||
* *tout = tin + span
|
||||
* *tout = tin + span
|
||||
*
|
||||
* returns 0 if successful
|
||||
* returns -1 if it fails
|
||||
* returns 0 if successful
|
||||
* returns -1 if it fails
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout)
|
||||
PGTYPEStimestamp_add_interval(timestamp * tin, interval * span, timestamp * tout)
|
||||
{
|
||||
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(*tin))
|
||||
*tout = *tin;
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
if (span->month != 0)
|
||||
{
|
||||
struct tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
|
||||
if (timestamp2tm(*tin, NULL, tm, &fsec, NULL) !=0)
|
||||
return -1;
|
||||
tm->tm_mon += span->month;
|
||||
if (tm->tm_mon > MONTHS_PER_YEAR)
|
||||
{
|
||||
tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
|
||||
tm->tm_mon = (tm->tm_mon - 1) % MONTHS_PER_YEAR + 1;
|
||||
}
|
||||
else if (tm->tm_mon < 1)
|
||||
{
|
||||
tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
|
||||
tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
|
||||
}
|
||||
|
||||
|
||||
/* adjust for end of month boundary problems... */
|
||||
if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
||||
tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
|
||||
|
||||
|
||||
if (tm2timestamp(tm, fsec, NULL, tin) !=0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
*tin +=span->time;
|
||||
*tout = *tin;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(*tin))
|
||||
*tout = *tin;
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
if (span->month != 0)
|
||||
{
|
||||
struct tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
|
||||
if (timestamp2tm(*tin, NULL, tm, &fsec, NULL) != 0)
|
||||
return -1;
|
||||
tm->tm_mon += span->month;
|
||||
if (tm->tm_mon > MONTHS_PER_YEAR)
|
||||
{
|
||||
tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
|
||||
tm->tm_mon = (tm->tm_mon - 1) % MONTHS_PER_YEAR + 1;
|
||||
}
|
||||
else if (tm->tm_mon < 1)
|
||||
{
|
||||
tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
|
||||
tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
|
||||
}
|
||||
|
||||
|
||||
/* adjust for end of month boundary problems... */
|
||||
if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
||||
tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
|
||||
|
||||
|
||||
if (tm2timestamp(tm, fsec, NULL, tin) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
*tin += span->time;
|
||||
*tout = *tin;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* subtract an interval from a time stamp
|
||||
*
|
||||
* *tout = tin - span
|
||||
* *tout = tin - span
|
||||
*
|
||||
* returns 0 if successful
|
||||
* returns -1 if it fails
|
||||
* returns 0 if successful
|
||||
* returns -1 if it fails
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout)
|
||||
{
|
||||
interval tspan;
|
||||
|
||||
tspan.month = -span->month;
|
||||
tspan.time = -span->time;
|
||||
|
||||
|
||||
return PGTYPEStimestamp_add_interval(tin, &tspan, tout );
|
||||
}
|
||||
|
||||
int
|
||||
PGTYPEStimestamp_sub_interval(timestamp * tin, interval * span, timestamp * tout)
|
||||
{
|
||||
interval tspan;
|
||||
|
||||
tspan.month = -span->month;
|
||||
tspan.time = -span->time;
|
||||
|
||||
|
||||
return PGTYPEStimestamp_add_interval(tin, &tspan, tout);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.92 2005/08/29 01:32:00 tgl Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.93 2005/10/15 02:49:47 momjian Exp $ */
|
||||
|
||||
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
|
||||
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
|
||||
@ -43,7 +43,7 @@ help(const char *progname)
|
||||
printf(" -c automatically generate C code from embedded SQL code;\n"
|
||||
" currently this works for EXEC SQL TYPE\n");
|
||||
printf(" -C MODE set compatibility mode;\n"
|
||||
" MODE may be one of \"INFORMIX\", \"INFORMIX_SE\"\n");
|
||||
" MODE may be one of \"INFORMIX\", \"INFORMIX_SE\"\n");
|
||||
#ifdef YYDEBUG
|
||||
printf(" -d generate parser debug output\n");
|
||||
#endif
|
||||
@ -431,8 +431,8 @@ main(int argc, char *const argv[])
|
||||
if (!(ptr->opened))
|
||||
{
|
||||
/*
|
||||
* Does not really make sense to declare a cursor
|
||||
* but not open it
|
||||
* Does not really make sense to declare a cursor but
|
||||
* not open it
|
||||
*/
|
||||
snprintf(errortext, sizeof(errortext), "cursor \"%s\" has been declared but not opened\n", ptr->name);
|
||||
mmerror(PARSE_ERROR, ET_WARNING, errortext);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* lexical token lookup for reserved words in postgres embedded SQL
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.30 2004/09/27 09:59:17 meskes Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.31 2005/10/15 02:49:47 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -63,8 +63,8 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"section", SQL_SECTION},
|
||||
{"short", SQL_SHORT},
|
||||
{"signed", SQL_SIGNED},
|
||||
{"sql", SQL_SQL}, /* strange thing, used for into sql
|
||||
* descriptor MYDESC; */
|
||||
{"sql", SQL_SQL}, /* strange thing, used for into sql descriptor
|
||||
* MYDESC; */
|
||||
{"sqlerror", SQL_SQLERROR},
|
||||
{"sqlprint", SQL_SQLPRINT},
|
||||
{"sqlwarning", SQL_SQLWARNING},
|
||||
@ -103,12 +103,12 @@ ScanECPGKeywordLookup(char *text)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since it
|
||||
* may produce the wrong translation in some locales (eg, Turkish),
|
||||
* and we don't trust isupper() very much either. In an ASCII-based
|
||||
* encoding the tests against A and Z are sufficient, but we also
|
||||
* check isupper() so that we will work correctly under EBCDIC. The
|
||||
* actual case conversion step should work for either ASCII or EBCDIC.
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since it may
|
||||
* produce the wrong translation in some locales (eg, Turkish), and we
|
||||
* don't trust isupper() very much either. In an ASCII-based encoding the
|
||||
* tests against A and Z are sufficient, but we also check isupper() so
|
||||
* that we will work correctly under EBCDIC. The actual case conversion
|
||||
* step should work for either ASCII or EBCDIC.
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.69 2005/10/04 13:28:21 meskes Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.70 2005/10/15 02:49:47 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,322 +43,322 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"analyze", ANALYZE},
|
||||
{"and", AND},
|
||||
{"any", ANY},
|
||||
{"array", ARRAY},
|
||||
{"as", AS},
|
||||
{"asc", ASC},
|
||||
{"assertion", ASSERTION},
|
||||
{"assignment", ASSIGNMENT},
|
||||
{"asymmetric", ASYMMETRIC},
|
||||
{"at", AT},
|
||||
{"authorization", AUTHORIZATION},
|
||||
{"backward", BACKWARD},
|
||||
{"before", BEFORE},
|
||||
{"begin", BEGIN_P},
|
||||
{"between", BETWEEN},
|
||||
{"bigint", BIGINT},
|
||||
{"binary", BINARY},
|
||||
{"bit", BIT},
|
||||
{"boolean", BOOLEAN_P},
|
||||
{"both", BOTH},
|
||||
{"by", BY},
|
||||
{"cache", CACHE},
|
||||
{"called", CALLED},
|
||||
{"cascade", CASCADE},
|
||||
{"case", CASE},
|
||||
{"cast", CAST},
|
||||
{"chain", CHAIN},
|
||||
{"char", CHAR_P},
|
||||
{"character", CHARACTER},
|
||||
{"characteristics", CHARACTERISTICS},
|
||||
{"check", CHECK},
|
||||
{"checkpoint", CHECKPOINT},
|
||||
{"class", CLASS},
|
||||
{"close", CLOSE},
|
||||
{"cluster", CLUSTER},
|
||||
{"coalesce", COALESCE},
|
||||
{"collate", COLLATE},
|
||||
{"column", COLUMN},
|
||||
{"comment", COMMENT},
|
||||
{"commit", COMMIT},
|
||||
{"committed", COMMITTED},
|
||||
{"connection", CONNECTION},
|
||||
{"constraint", CONSTRAINT},
|
||||
{"constraints", CONSTRAINTS},
|
||||
{"conversion", CONVERSION_P},
|
||||
{"convert", CONVERT},
|
||||
{"copy", COPY},
|
||||
{"create", CREATE},
|
||||
{"createdb", CREATEDB},
|
||||
{"createrole", CREATEROLE},
|
||||
{"createuser", CREATEUSER},
|
||||
{"cross", CROSS},
|
||||
{"csv", CSV},
|
||||
{"current_date", CURRENT_DATE},
|
||||
{"current_role", CURRENT_ROLE},
|
||||
{"current_time", CURRENT_TIME},
|
||||
{"current_timestamp", CURRENT_TIMESTAMP},
|
||||
{"cursor", CURSOR},
|
||||
{"cycle", CYCLE},
|
||||
{"database", DATABASE},
|
||||
{"day", DAY_P},
|
||||
{"deallocate", DEALLOCATE},
|
||||
{"dec", DEC},
|
||||
{"decimal", DECIMAL_P},
|
||||
{"declare", DECLARE},
|
||||
{"default", DEFAULT},
|
||||
{"defaults", DEFAULTS},
|
||||
{"deferrable", DEFERRABLE},
|
||||
{"deferred", DEFERRED},
|
||||
{"definer", DEFINER},
|
||||
{"delete", DELETE_P},
|
||||
{"delimiter", DELIMITER},
|
||||
{"delimiters", DELIMITERS},
|
||||
{"desc", DESC},
|
||||
{"disable", DISABLE_P},
|
||||
{"distinct", DISTINCT},
|
||||
{"do", DO},
|
||||
{"domain", DOMAIN_P},
|
||||
{"double", DOUBLE_P},
|
||||
{"drop", DROP},
|
||||
{"each", EACH},
|
||||
{"else", ELSE},
|
||||
{"enable", ENABLE_P},
|
||||
{"encoding", ENCODING},
|
||||
{"encrypted", ENCRYPTED},
|
||||
{"end", END_P},
|
||||
{"escape", ESCAPE},
|
||||
{"except", EXCEPT},
|
||||
{"excluding", EXCLUDING},
|
||||
{"exclusive", EXCLUSIVE},
|
||||
{"execute", EXECUTE},
|
||||
{"exists", EXISTS},
|
||||
{"explain", EXPLAIN},
|
||||
{"external", EXTERNAL},
|
||||
{"extract", EXTRACT},
|
||||
{"false", FALSE_P},
|
||||
{"fetch", FETCH},
|
||||
{"first", FIRST_P},
|
||||
{"float", FLOAT_P},
|
||||
{"for", FOR},
|
||||
{"force", FORCE},
|
||||
{"foreign", FOREIGN},
|
||||
{"forward", FORWARD},
|
||||
{"freeze", FREEZE},
|
||||
{"from", FROM},
|
||||
{"full", FULL},
|
||||
{"function", FUNCTION},
|
||||
{"get", GET},
|
||||
{"global", GLOBAL},
|
||||
{"grant", GRANT},
|
||||
{"granted", GRANTED},
|
||||
{"greatest", GREATEST},
|
||||
{"group", GROUP_P},
|
||||
{"handler", HANDLER},
|
||||
{"having", HAVING},
|
||||
{"header", HEADER},
|
||||
{"hold", HOLD},
|
||||
{"hour", HOUR_P},
|
||||
{"ilike", ILIKE},
|
||||
{"immediate", IMMEDIATE},
|
||||
{"immutable", IMMUTABLE},
|
||||
{"implicit", IMPLICIT_P},
|
||||
{"in", IN_P},
|
||||
{"including", INCLUDING},
|
||||
{"increment", INCREMENT},
|
||||
{"index", INDEX},
|
||||
{"inherit", INHERIT},
|
||||
{"inherits", INHERITS},
|
||||
{"initially", INITIALLY},
|
||||
{"inner", INNER_P},
|
||||
{"inout", INOUT},
|
||||
{"input", INPUT_P},
|
||||
{"insensitive", INSENSITIVE},
|
||||
{"insert", INSERT},
|
||||
{"instead", INSTEAD},
|
||||
{"int", INT_P},
|
||||
{"integer", INTEGER},
|
||||
{"intersect", INTERSECT},
|
||||
{"interval", INTERVAL},
|
||||
{"into", INTO},
|
||||
{"invoker", INVOKER},
|
||||
{"is", IS},
|
||||
{"isnull", ISNULL},
|
||||
{"isolation", ISOLATION},
|
||||
{"join", JOIN},
|
||||
{"key", KEY},
|
||||
{"lancompiler", LANCOMPILER},
|
||||
{"language", LANGUAGE},
|
||||
{"large", LARGE_P},
|
||||
{"last", LAST_P},
|
||||
{"leading", LEADING},
|
||||
{"least", LEAST},
|
||||
{"left", LEFT},
|
||||
{"level", LEVEL},
|
||||
{"like", LIKE},
|
||||
{"limit", LIMIT},
|
||||
{"listen", LISTEN},
|
||||
{"load", LOAD},
|
||||
{"local", LOCAL},
|
||||
{"location", LOCATION},
|
||||
{"lock", LOCK_P},
|
||||
{"login", LOGIN_P},
|
||||
{"match", MATCH},
|
||||
{"maxvalue", MAXVALUE},
|
||||
{"minute", MINUTE_P},
|
||||
{"minvalue", MINVALUE},
|
||||
{"mode", MODE},
|
||||
{"month", MONTH_P},
|
||||
{"move", MOVE},
|
||||
{"names", NAMES},
|
||||
{"national", NATIONAL},
|
||||
{"natural", NATURAL},
|
||||
{"nchar", NCHAR},
|
||||
{"new", NEW},
|
||||
{"next", NEXT},
|
||||
{"no", NO},
|
||||
{"nocreatedb", NOCREATEDB},
|
||||
{"nocreaterole", NOCREATEROLE},
|
||||
{"nocreateuser", NOCREATEUSER},
|
||||
{"noinherit", NOINHERIT},
|
||||
{"nologin", NOLOGIN_P},
|
||||
{"none", NONE},
|
||||
{"nosuperuser", NOSUPERUSER},
|
||||
{"not", NOT},
|
||||
{"nothing", NOTHING},
|
||||
{"notify", NOTIFY},
|
||||
{"notnull", NOTNULL},
|
||||
{"nowait", NOWAIT},
|
||||
{"null", NULL_P},
|
||||
{"nullif", NULLIF},
|
||||
{"numeric", NUMERIC},
|
||||
{"object", OBJECT_P},
|
||||
{"of", OF},
|
||||
{"off", OFF},
|
||||
{"offset", OFFSET},
|
||||
{"oids", OIDS},
|
||||
{"old", OLD},
|
||||
{"on", ON},
|
||||
{"only", ONLY},
|
||||
{"operator", OPERATOR},
|
||||
{"option", OPTION},
|
||||
{"or", OR},
|
||||
{"order", ORDER},
|
||||
{"out", OUT_P},
|
||||
{"outer", OUTER_P},
|
||||
{"overlaps", OVERLAPS},
|
||||
{"owner", OWNER},
|
||||
{"partial", PARTIAL},
|
||||
{"password", PASSWORD},
|
||||
{"position", POSITION},
|
||||
{"precision", PRECISION},
|
||||
{"prepare", PREPARE},
|
||||
{"prepared", PREPARED},
|
||||
{"preserve", PRESERVE},
|
||||
{"primary", PRIMARY},
|
||||
{"prior", PRIOR},
|
||||
{"privileges", PRIVILEGES},
|
||||
{"procedural", PROCEDURAL},
|
||||
{"procedure", PROCEDURE},
|
||||
{"quote", QUOTE},
|
||||
{"read", READ},
|
||||
{"real", REAL},
|
||||
{"recheck", RECHECK},
|
||||
{"references", REFERENCES},
|
||||
{"reindex", REINDEX},
|
||||
{"relative", RELATIVE_P},
|
||||
{"release", RELEASE},
|
||||
{"rename", RENAME},
|
||||
{"repeatable", REPEATABLE},
|
||||
{"replace", REPLACE},
|
||||
{"reset", RESET},
|
||||
{"restart", RESTART},
|
||||
{"restrict", RESTRICT},
|
||||
{"returns", RETURNS},
|
||||
{"revoke", REVOKE},
|
||||
{"right", RIGHT},
|
||||
{"role", ROLE},
|
||||
{"rollback", ROLLBACK},
|
||||
{"row", ROW},
|
||||
{"rows", ROWS},
|
||||
{"rule", RULE},
|
||||
{"savepoint", SAVEPOINT},
|
||||
{"schema", SCHEMA},
|
||||
{"scroll", SCROLL},
|
||||
{"second", SECOND_P},
|
||||
{"security", SECURITY},
|
||||
{"select", SELECT},
|
||||
{"sequence", SEQUENCE},
|
||||
{"serializable", SERIALIZABLE},
|
||||
{"session", SESSION},
|
||||
{"session_user", SESSION_USER},
|
||||
{"set", SET},
|
||||
{"setof", SETOF},
|
||||
{"share", SHARE},
|
||||
{"show", SHOW},
|
||||
{"similar", SIMILAR},
|
||||
{"simple", SIMPLE},
|
||||
{"smallint", SMALLINT},
|
||||
{"some", SOME},
|
||||
{"stable", STABLE},
|
||||
{"start", START},
|
||||
{"statement", STATEMENT},
|
||||
{"statistics", STATISTICS},
|
||||
{"stdin", STDIN},
|
||||
{"stdout", STDOUT},
|
||||
{"storage", STORAGE},
|
||||
{"strict", STRICT_P},
|
||||
{"substring", SUBSTRING},
|
||||
{"superuser", SUPERUSER_P},
|
||||
{"symmetric", SYMMETRIC},
|
||||
{"sysid", SYSID},
|
||||
{"system", SYSTEM_P},
|
||||
{"table", TABLE},
|
||||
{"tablespace", TABLESPACE},
|
||||
{"temp", TEMP},
|
||||
{"template", TEMPLATE},
|
||||
{"temporary", TEMPORARY},
|
||||
{"then", THEN},
|
||||
{"time", TIME},
|
||||
{"timestamp", TIMESTAMP},
|
||||
{"to", TO},
|
||||
{"toast", TOAST},
|
||||
{"trailing", TRAILING},
|
||||
{"transaction", TRANSACTION},
|
||||
{"treat", TREAT},
|
||||
{"trigger", TRIGGER},
|
||||
{"trim", TRIM},
|
||||
{"true", TRUE_P},
|
||||
{"truncate", TRUNCATE},
|
||||
{"trusted", TRUSTED},
|
||||
{"type", TYPE_P},
|
||||
{"uncommitted", UNCOMMITTED},
|
||||
{"unencrypted", UNENCRYPTED},
|
||||
{"union", UNION},
|
||||
{"unique", UNIQUE},
|
||||
{"unknown", UNKNOWN},
|
||||
{"unlisten", UNLISTEN},
|
||||
{"until", UNTIL},
|
||||
{"update", UPDATE},
|
||||
{"user", USER},
|
||||
{"using", USING},
|
||||
{"vacuum", VACUUM},
|
||||
{"valid", VALID},
|
||||
{"validator", VALIDATOR},
|
||||
{"values", VALUES},
|
||||
{"varchar", VARCHAR},
|
||||
{"varying", VARYING},
|
||||
{"verbose", VERBOSE},
|
||||
{"view", VIEW},
|
||||
{"volatile", VOLATILE},
|
||||
{"when", WHEN},
|
||||
{"where", WHERE},
|
||||
{"with", WITH},
|
||||
{"without", WITHOUT},
|
||||
{"work", WORK},
|
||||
{"write", WRITE},
|
||||
{"year", YEAR_P},
|
||||
{"zone", ZONE},
|
||||
};
|
||||
{"array", ARRAY},
|
||||
{"as", AS},
|
||||
{"asc", ASC},
|
||||
{"assertion", ASSERTION},
|
||||
{"assignment", ASSIGNMENT},
|
||||
{"asymmetric", ASYMMETRIC},
|
||||
{"at", AT},
|
||||
{"authorization", AUTHORIZATION},
|
||||
{"backward", BACKWARD},
|
||||
{"before", BEFORE},
|
||||
{"begin", BEGIN_P},
|
||||
{"between", BETWEEN},
|
||||
{"bigint", BIGINT},
|
||||
{"binary", BINARY},
|
||||
{"bit", BIT},
|
||||
{"boolean", BOOLEAN_P},
|
||||
{"both", BOTH},
|
||||
{"by", BY},
|
||||
{"cache", CACHE},
|
||||
{"called", CALLED},
|
||||
{"cascade", CASCADE},
|
||||
{"case", CASE},
|
||||
{"cast", CAST},
|
||||
{"chain", CHAIN},
|
||||
{"char", CHAR_P},
|
||||
{"character", CHARACTER},
|
||||
{"characteristics", CHARACTERISTICS},
|
||||
{"check", CHECK},
|
||||
{"checkpoint", CHECKPOINT},
|
||||
{"class", CLASS},
|
||||
{"close", CLOSE},
|
||||
{"cluster", CLUSTER},
|
||||
{"coalesce", COALESCE},
|
||||
{"collate", COLLATE},
|
||||
{"column", COLUMN},
|
||||
{"comment", COMMENT},
|
||||
{"commit", COMMIT},
|
||||
{"committed", COMMITTED},
|
||||
{"connection", CONNECTION},
|
||||
{"constraint", CONSTRAINT},
|
||||
{"constraints", CONSTRAINTS},
|
||||
{"conversion", CONVERSION_P},
|
||||
{"convert", CONVERT},
|
||||
{"copy", COPY},
|
||||
{"create", CREATE},
|
||||
{"createdb", CREATEDB},
|
||||
{"createrole", CREATEROLE},
|
||||
{"createuser", CREATEUSER},
|
||||
{"cross", CROSS},
|
||||
{"csv", CSV},
|
||||
{"current_date", CURRENT_DATE},
|
||||
{"current_role", CURRENT_ROLE},
|
||||
{"current_time", CURRENT_TIME},
|
||||
{"current_timestamp", CURRENT_TIMESTAMP},
|
||||
{"cursor", CURSOR},
|
||||
{"cycle", CYCLE},
|
||||
{"database", DATABASE},
|
||||
{"day", DAY_P},
|
||||
{"deallocate", DEALLOCATE},
|
||||
{"dec", DEC},
|
||||
{"decimal", DECIMAL_P},
|
||||
{"declare", DECLARE},
|
||||
{"default", DEFAULT},
|
||||
{"defaults", DEFAULTS},
|
||||
{"deferrable", DEFERRABLE},
|
||||
{"deferred", DEFERRED},
|
||||
{"definer", DEFINER},
|
||||
{"delete", DELETE_P},
|
||||
{"delimiter", DELIMITER},
|
||||
{"delimiters", DELIMITERS},
|
||||
{"desc", DESC},
|
||||
{"disable", DISABLE_P},
|
||||
{"distinct", DISTINCT},
|
||||
{"do", DO},
|
||||
{"domain", DOMAIN_P},
|
||||
{"double", DOUBLE_P},
|
||||
{"drop", DROP},
|
||||
{"each", EACH},
|
||||
{"else", ELSE},
|
||||
{"enable", ENABLE_P},
|
||||
{"encoding", ENCODING},
|
||||
{"encrypted", ENCRYPTED},
|
||||
{"end", END_P},
|
||||
{"escape", ESCAPE},
|
||||
{"except", EXCEPT},
|
||||
{"excluding", EXCLUDING},
|
||||
{"exclusive", EXCLUSIVE},
|
||||
{"execute", EXECUTE},
|
||||
{"exists", EXISTS},
|
||||
{"explain", EXPLAIN},
|
||||
{"external", EXTERNAL},
|
||||
{"extract", EXTRACT},
|
||||
{"false", FALSE_P},
|
||||
{"fetch", FETCH},
|
||||
{"first", FIRST_P},
|
||||
{"float", FLOAT_P},
|
||||
{"for", FOR},
|
||||
{"force", FORCE},
|
||||
{"foreign", FOREIGN},
|
||||
{"forward", FORWARD},
|
||||
{"freeze", FREEZE},
|
||||
{"from", FROM},
|
||||
{"full", FULL},
|
||||
{"function", FUNCTION},
|
||||
{"get", GET},
|
||||
{"global", GLOBAL},
|
||||
{"grant", GRANT},
|
||||
{"granted", GRANTED},
|
||||
{"greatest", GREATEST},
|
||||
{"group", GROUP_P},
|
||||
{"handler", HANDLER},
|
||||
{"having", HAVING},
|
||||
{"header", HEADER},
|
||||
{"hold", HOLD},
|
||||
{"hour", HOUR_P},
|
||||
{"ilike", ILIKE},
|
||||
{"immediate", IMMEDIATE},
|
||||
{"immutable", IMMUTABLE},
|
||||
{"implicit", IMPLICIT_P},
|
||||
{"in", IN_P},
|
||||
{"including", INCLUDING},
|
||||
{"increment", INCREMENT},
|
||||
{"index", INDEX},
|
||||
{"inherit", INHERIT},
|
||||
{"inherits", INHERITS},
|
||||
{"initially", INITIALLY},
|
||||
{"inner", INNER_P},
|
||||
{"inout", INOUT},
|
||||
{"input", INPUT_P},
|
||||
{"insensitive", INSENSITIVE},
|
||||
{"insert", INSERT},
|
||||
{"instead", INSTEAD},
|
||||
{"int", INT_P},
|
||||
{"integer", INTEGER},
|
||||
{"intersect", INTERSECT},
|
||||
{"interval", INTERVAL},
|
||||
{"into", INTO},
|
||||
{"invoker", INVOKER},
|
||||
{"is", IS},
|
||||
{"isnull", ISNULL},
|
||||
{"isolation", ISOLATION},
|
||||
{"join", JOIN},
|
||||
{"key", KEY},
|
||||
{"lancompiler", LANCOMPILER},
|
||||
{"language", LANGUAGE},
|
||||
{"large", LARGE_P},
|
||||
{"last", LAST_P},
|
||||
{"leading", LEADING},
|
||||
{"least", LEAST},
|
||||
{"left", LEFT},
|
||||
{"level", LEVEL},
|
||||
{"like", LIKE},
|
||||
{"limit", LIMIT},
|
||||
{"listen", LISTEN},
|
||||
{"load", LOAD},
|
||||
{"local", LOCAL},
|
||||
{"location", LOCATION},
|
||||
{"lock", LOCK_P},
|
||||
{"login", LOGIN_P},
|
||||
{"match", MATCH},
|
||||
{"maxvalue", MAXVALUE},
|
||||
{"minute", MINUTE_P},
|
||||
{"minvalue", MINVALUE},
|
||||
{"mode", MODE},
|
||||
{"month", MONTH_P},
|
||||
{"move", MOVE},
|
||||
{"names", NAMES},
|
||||
{"national", NATIONAL},
|
||||
{"natural", NATURAL},
|
||||
{"nchar", NCHAR},
|
||||
{"new", NEW},
|
||||
{"next", NEXT},
|
||||
{"no", NO},
|
||||
{"nocreatedb", NOCREATEDB},
|
||||
{"nocreaterole", NOCREATEROLE},
|
||||
{"nocreateuser", NOCREATEUSER},
|
||||
{"noinherit", NOINHERIT},
|
||||
{"nologin", NOLOGIN_P},
|
||||
{"none", NONE},
|
||||
{"nosuperuser", NOSUPERUSER},
|
||||
{"not", NOT},
|
||||
{"nothing", NOTHING},
|
||||
{"notify", NOTIFY},
|
||||
{"notnull", NOTNULL},
|
||||
{"nowait", NOWAIT},
|
||||
{"null", NULL_P},
|
||||
{"nullif", NULLIF},
|
||||
{"numeric", NUMERIC},
|
||||
{"object", OBJECT_P},
|
||||
{"of", OF},
|
||||
{"off", OFF},
|
||||
{"offset", OFFSET},
|
||||
{"oids", OIDS},
|
||||
{"old", OLD},
|
||||
{"on", ON},
|
||||
{"only", ONLY},
|
||||
{"operator", OPERATOR},
|
||||
{"option", OPTION},
|
||||
{"or", OR},
|
||||
{"order", ORDER},
|
||||
{"out", OUT_P},
|
||||
{"outer", OUTER_P},
|
||||
{"overlaps", OVERLAPS},
|
||||
{"owner", OWNER},
|
||||
{"partial", PARTIAL},
|
||||
{"password", PASSWORD},
|
||||
{"position", POSITION},
|
||||
{"precision", PRECISION},
|
||||
{"prepare", PREPARE},
|
||||
{"prepared", PREPARED},
|
||||
{"preserve", PRESERVE},
|
||||
{"primary", PRIMARY},
|
||||
{"prior", PRIOR},
|
||||
{"privileges", PRIVILEGES},
|
||||
{"procedural", PROCEDURAL},
|
||||
{"procedure", PROCEDURE},
|
||||
{"quote", QUOTE},
|
||||
{"read", READ},
|
||||
{"real", REAL},
|
||||
{"recheck", RECHECK},
|
||||
{"references", REFERENCES},
|
||||
{"reindex", REINDEX},
|
||||
{"relative", RELATIVE_P},
|
||||
{"release", RELEASE},
|
||||
{"rename", RENAME},
|
||||
{"repeatable", REPEATABLE},
|
||||
{"replace", REPLACE},
|
||||
{"reset", RESET},
|
||||
{"restart", RESTART},
|
||||
{"restrict", RESTRICT},
|
||||
{"returns", RETURNS},
|
||||
{"revoke", REVOKE},
|
||||
{"right", RIGHT},
|
||||
{"role", ROLE},
|
||||
{"rollback", ROLLBACK},
|
||||
{"row", ROW},
|
||||
{"rows", ROWS},
|
||||
{"rule", RULE},
|
||||
{"savepoint", SAVEPOINT},
|
||||
{"schema", SCHEMA},
|
||||
{"scroll", SCROLL},
|
||||
{"second", SECOND_P},
|
||||
{"security", SECURITY},
|
||||
{"select", SELECT},
|
||||
{"sequence", SEQUENCE},
|
||||
{"serializable", SERIALIZABLE},
|
||||
{"session", SESSION},
|
||||
{"session_user", SESSION_USER},
|
||||
{"set", SET},
|
||||
{"setof", SETOF},
|
||||
{"share", SHARE},
|
||||
{"show", SHOW},
|
||||
{"similar", SIMILAR},
|
||||
{"simple", SIMPLE},
|
||||
{"smallint", SMALLINT},
|
||||
{"some", SOME},
|
||||
{"stable", STABLE},
|
||||
{"start", START},
|
||||
{"statement", STATEMENT},
|
||||
{"statistics", STATISTICS},
|
||||
{"stdin", STDIN},
|
||||
{"stdout", STDOUT},
|
||||
{"storage", STORAGE},
|
||||
{"strict", STRICT_P},
|
||||
{"substring", SUBSTRING},
|
||||
{"superuser", SUPERUSER_P},
|
||||
{"symmetric", SYMMETRIC},
|
||||
{"sysid", SYSID},
|
||||
{"system", SYSTEM_P},
|
||||
{"table", TABLE},
|
||||
{"tablespace", TABLESPACE},
|
||||
{"temp", TEMP},
|
||||
{"template", TEMPLATE},
|
||||
{"temporary", TEMPORARY},
|
||||
{"then", THEN},
|
||||
{"time", TIME},
|
||||
{"timestamp", TIMESTAMP},
|
||||
{"to", TO},
|
||||
{"toast", TOAST},
|
||||
{"trailing", TRAILING},
|
||||
{"transaction", TRANSACTION},
|
||||
{"treat", TREAT},
|
||||
{"trigger", TRIGGER},
|
||||
{"trim", TRIM},
|
||||
{"true", TRUE_P},
|
||||
{"truncate", TRUNCATE},
|
||||
{"trusted", TRUSTED},
|
||||
{"type", TYPE_P},
|
||||
{"uncommitted", UNCOMMITTED},
|
||||
{"unencrypted", UNENCRYPTED},
|
||||
{"union", UNION},
|
||||
{"unique", UNIQUE},
|
||||
{"unknown", UNKNOWN},
|
||||
{"unlisten", UNLISTEN},
|
||||
{"until", UNTIL},
|
||||
{"update", UPDATE},
|
||||
{"user", USER},
|
||||
{"using", USING},
|
||||
{"vacuum", VACUUM},
|
||||
{"valid", VALID},
|
||||
{"validator", VALIDATOR},
|
||||
{"values", VALUES},
|
||||
{"varchar", VARCHAR},
|
||||
{"varying", VARYING},
|
||||
{"verbose", VERBOSE},
|
||||
{"view", VIEW},
|
||||
{"volatile", VOLATILE},
|
||||
{"when", WHEN},
|
||||
{"where", WHERE},
|
||||
{"with", WITH},
|
||||
{"without", WITHOUT},
|
||||
{"work", WORK},
|
||||
{"write", WRITE},
|
||||
{"year", YEAR_P},
|
||||
{"zone", ZONE},
|
||||
};
|
||||
|
||||
/*
|
||||
* ScanKeywordLookup - see if a given word is a keyword
|
||||
@ -372,54 +372,53 @@ static ScanKeyword ScanKeywords[] = {
|
||||
* keywords are to be matched in this way even though non-keyword identifiers
|
||||
* receive a different case-normalization mapping.
|
||||
*/
|
||||
ScanKeyword *
|
||||
ScanKeywordLookup(char *text)
|
||||
{
|
||||
int len,
|
||||
i;
|
||||
char word[NAMEDATALEN];
|
||||
ScanKeyword *low;
|
||||
ScanKeyword *high;
|
||||
|
||||
len = strlen(text);
|
||||
/* We assume all keywords are shorter than NAMEDATALEN. */
|
||||
if (len >= NAMEDATALEN)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Apply an ASCII-only downcasing. We must not use tolower()
|
||||
* since it may produce the wrong translation in some locales (eg,
|
||||
* Turkish).
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char ch = text[i];
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z')
|
||||
ch += 'a' - 'A';
|
||||
word[i] = ch;
|
||||
}
|
||||
word[len] = '\0';
|
||||
|
||||
/*
|
||||
* Now do a binary search using plain strcmp() comparison.
|
||||
*/
|
||||
low = &ScanKeywords[0];
|
||||
high = endof(ScanKeywords) - 1;
|
||||
while (low <= high)
|
||||
{
|
||||
ScanKeyword *middle;
|
||||
int difference;
|
||||
|
||||
middle = low + (high - low) / 2;
|
||||
difference = strcmp(middle->name, word);
|
||||
if (difference == 0)
|
||||
return middle;
|
||||
else if (difference < 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
ScanKeyword *
|
||||
ScanKeywordLookup(char *text)
|
||||
{
|
||||
int len,
|
||||
i;
|
||||
char word[NAMEDATALEN];
|
||||
ScanKeyword *low;
|
||||
ScanKeyword *high;
|
||||
|
||||
len = strlen(text);
|
||||
/* We assume all keywords are shorter than NAMEDATALEN. */
|
||||
if (len >= NAMEDATALEN)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since it may
|
||||
* produce the wrong translation in some locales (eg, Turkish).
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char ch = text[i];
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z')
|
||||
ch += 'a' - 'A';
|
||||
word[i] = ch;
|
||||
}
|
||||
word[len] = '\0';
|
||||
|
||||
/*
|
||||
* Now do a binary search using plain strcmp() comparison.
|
||||
*/
|
||||
low = &ScanKeywords[0];
|
||||
high = endof(ScanKeywords) - 1;
|
||||
while (low <= high)
|
||||
{
|
||||
ScanKeyword *middle;
|
||||
int difference;
|
||||
|
||||
middle = low + (high - low) / 2;
|
||||
difference = strcmp(middle->name, word);
|
||||
if (difference == 0)
|
||||
return middle;
|
||||
else if (difference < 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
high = middle - 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -173,8 +173,7 @@ get_type(enum ECPGttype type)
|
||||
case ECPGt_NO_INDICATOR: /* no indicator */
|
||||
return ("ECPGt_NO_INDICATOR");
|
||||
break;
|
||||
case ECPGt_char_variable: /* string that should not be
|
||||
* quoted */
|
||||
case ECPGt_char_variable: /* string that should not be quoted */
|
||||
return ("ECPGt_char_variable");
|
||||
break;
|
||||
case ECPGt_const: /* constant string quoted */
|
||||
@ -257,7 +256,7 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
|
||||
|
||||
ECPGdump_a_simple(o, name,
|
||||
type->u.element->type,
|
||||
type->u.element->size, type->size, NULL, prefix);
|
||||
type->u.element->size, type->size, NULL, prefix);
|
||||
|
||||
if (ind_type != NULL)
|
||||
{
|
||||
@ -358,7 +357,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
|
||||
*/
|
||||
if ((atoi(varcharsize) > 1 ||
|
||||
(atoi(arrsize) > 0) ||
|
||||
(atoi(varcharsize) == 0 && strcmp(varcharsize, "0") != 0) ||
|
||||
(atoi(varcharsize) == 0 && strcmp(varcharsize, "0") != 0) ||
|
||||
(atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0))
|
||||
&& siz == NULL)
|
||||
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
|
||||
@ -386,8 +385,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
|
||||
case ECPGt_date:
|
||||
|
||||
/*
|
||||
* we have to use a pointer and translate the variable
|
||||
* type
|
||||
* we have to use a pointer and translate the variable type
|
||||
*/
|
||||
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
|
||||
sprintf(offset, "sizeof(date)");
|
||||
@ -395,8 +393,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
|
||||
case ECPGt_timestamp:
|
||||
|
||||
/*
|
||||
* we have to use a pointer and translate the variable
|
||||
* type
|
||||
* we have to use a pointer and translate the variable type
|
||||
*/
|
||||
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
|
||||
sprintf(offset, "sizeof(timestamp)");
|
||||
@ -445,9 +442,8 @@ static void
|
||||
ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsiz, struct ECPGtype * type, struct ECPGtype * ind_type, const char *offsetarg, const char *prefix, const char *ind_prefix)
|
||||
{
|
||||
/*
|
||||
* If offset is NULL, then this is the first recursive level. If not
|
||||
* then we are in a struct in a struct and the offset is used as
|
||||
* offset.
|
||||
* If offset is NULL, then this is the first recursive level. If not then
|
||||
* we are in a struct in a struct and the offset is used as offset.
|
||||
*/
|
||||
struct ECPGstruct_member *p,
|
||||
*ind_p = NULL;
|
||||
|
@ -14,15 +14,14 @@ struct ECPGstruct_member
|
||||
struct ECPGtype
|
||||
{
|
||||
enum ECPGttype type;
|
||||
char *size; /* For array it is the number of elements.
|
||||
* For varchar it is the maxsize of the
|
||||
* area. */
|
||||
char *struct_sizeof; /* For a struct this is the sizeof() type
|
||||
* as string */
|
||||
char *size; /* For array it is the number of elements. For
|
||||
* varchar it is the maxsize of the area. */
|
||||
char *struct_sizeof; /* For a struct this is the sizeof() type as
|
||||
* string */
|
||||
union
|
||||
{
|
||||
struct ECPGtype *element; /* For an array this is the type
|
||||
* of the element */
|
||||
struct ECPGtype *element; /* For an array this is the type of
|
||||
* the element */
|
||||
struct ECPGstruct_member *members; /* A pointer to a list of
|
||||
* members. */
|
||||
} u;
|
||||
|
@ -58,8 +58,8 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
|
||||
int count;
|
||||
|
||||
/*
|
||||
* We don't care about what's inside the array braces
|
||||
* so just eat up the character
|
||||
* We don't care about what's inside the array braces so
|
||||
* just eat up the character
|
||||
*/
|
||||
for (count = 1, end = next + 1; count; end++)
|
||||
{
|
||||
@ -81,8 +81,8 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
|
||||
|
||||
switch (*end)
|
||||
{
|
||||
case '\0': /* found the end, but this time it has to
|
||||
* be an array element */
|
||||
case '\0': /* found the end, but this time it has to be
|
||||
* an array element */
|
||||
if (members->type->type != ECPGt_array)
|
||||
mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable %s", name);
|
||||
|
||||
@ -198,8 +198,8 @@ find_variable(char *name)
|
||||
if (*next == '[')
|
||||
{
|
||||
/*
|
||||
* We don't care about what's inside the array braces so just
|
||||
* eat up the characters
|
||||
* We don't care about what's inside the array braces so just eat
|
||||
* up the characters
|
||||
*/
|
||||
for (count = 1, end = next + 1; count; end++)
|
||||
{
|
||||
@ -410,8 +410,8 @@ dump_variables(struct arguments * list, int mode)
|
||||
return;
|
||||
|
||||
/*
|
||||
* The list is build up from the beginning so lets first dump the end
|
||||
* of the list:
|
||||
* The list is build up from the beginning so lets first dump the end of
|
||||
* the list:
|
||||
*/
|
||||
|
||||
dump_variables(list->next, mode);
|
||||
@ -550,8 +550,8 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
|
||||
if (atoi(*length) < 0)
|
||||
{
|
||||
/*
|
||||
* make sure we return length = -1 for arrays without
|
||||
* given bounds
|
||||
* make sure we return length = -1 for arrays without given
|
||||
* bounds
|
||||
*/
|
||||
if (atoi(*dimension) < 0 && !type_definition)
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.104 2005/10/08 19:32:58 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.105 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -64,7 +64,8 @@
|
||||
*/
|
||||
|
||||
#define STARTUP_MSG 7 /* Initialise a connection */
|
||||
#define STARTUP_KRB4_MSG 10 /* krb4 session follows. Not supported any more. */
|
||||
#define STARTUP_KRB4_MSG 10 /* krb4 session follows. Not supported any
|
||||
* more. */
|
||||
#define STARTUP_KRB5_MSG 11 /* krb5 session follows */
|
||||
#define STARTUP_PASSWORD_MSG 14 /* Password follows */
|
||||
|
||||
@ -139,7 +140,7 @@ pg_an_to_ln(char *aname)
|
||||
if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
|
||||
*p = '\0';
|
||||
#ifdef WIN32
|
||||
for (p = aname; *p ; p++)
|
||||
for (p = aname; *p; p++)
|
||||
*p = pg_tolower(*p);
|
||||
#endif
|
||||
|
||||
@ -265,9 +266,9 @@ pg_krb5_sendauth(char *PQerrormsg, int sock, const char *hostname, const char *s
|
||||
}
|
||||
|
||||
/*
|
||||
* libpq uses a non-blocking socket. But kerberos needs a blocking
|
||||
* socket, and we have to block somehow to do mutual authentication
|
||||
* anyway. So we temporarily make it blocking.
|
||||
* libpq uses a non-blocking socket. But kerberos needs a blocking socket,
|
||||
* and we have to block somehow to do mutual authentication anyway. So we
|
||||
* temporarily make it blocking.
|
||||
*/
|
||||
if (!pg_set_block(sock))
|
||||
{
|
||||
@ -291,11 +292,11 @@ pg_krb5_sendauth(char *PQerrormsg, int sock, const char *hostname, const char *s
|
||||
{
|
||||
#if defined(HAVE_KRB5_ERROR_TEXT_DATA)
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
|
||||
libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
|
||||
(int) err_ret->text.length, err_ret->text.data);
|
||||
#elif defined(HAVE_KRB5_ERROR_E_DATA)
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
|
||||
libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
|
||||
(int) err_ret->e_data->length,
|
||||
(const char *) err_ret->e_data->data);
|
||||
#else
|
||||
@ -321,7 +322,7 @@ pg_krb5_sendauth(char *PQerrormsg, int sock, const char *hostname, const char *s
|
||||
char sebuf[256];
|
||||
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("could not restore non-blocking mode on socket: %s\n"),
|
||||
libpq_gettext("could not restore non-blocking mode on socket: %s\n"),
|
||||
pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
ret = STATUS_ERROR;
|
||||
}
|
||||
@ -355,8 +356,8 @@ pg_local_sendauth(char *PQerrormsg, PGconn *conn)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The backend doesn't care what we send here, but it wants exactly
|
||||
* one character to force recvmsg() to block and wait for us.
|
||||
* The backend doesn't care what we send here, but it wants exactly one
|
||||
* character to force recvmsg() to block and wait for us.
|
||||
*/
|
||||
buf = '\0';
|
||||
iov.iov_base = &buf;
|
||||
@ -388,7 +389,7 @@ pg_local_sendauth(char *PQerrormsg, PGconn *conn)
|
||||
return STATUS_OK;
|
||||
#else
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("SCM_CRED authentication method not supported\n"));
|
||||
libpq_gettext("SCM_CRED authentication method not supported\n"));
|
||||
return STATUS_ERROR;
|
||||
#endif
|
||||
}
|
||||
@ -473,7 +474,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
|
||||
|
||||
case AUTH_REQ_KRB4:
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("Kerberos 4 authentication not supported\n"));
|
||||
libpq_gettext("Kerberos 4 authentication not supported\n"));
|
||||
return STATUS_ERROR;
|
||||
|
||||
case AUTH_REQ_KRB5:
|
||||
@ -490,7 +491,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
|
||||
break;
|
||||
#else
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("Kerberos 5 authentication not supported\n"));
|
||||
libpq_gettext("Kerberos 5 authentication not supported\n"));
|
||||
return STATUS_ERROR;
|
||||
#endif
|
||||
|
||||
@ -506,7 +507,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
|
||||
if (pg_password_sendauth(conn, password, areq) != STATUS_OK)
|
||||
{
|
||||
(void) snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"fe_sendauth: error sending password authentication\n");
|
||||
"fe_sendauth: error sending password authentication\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
break;
|
||||
@ -518,7 +519,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
|
||||
|
||||
default:
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("authentication method %u not supported\n"), areq);
|
||||
libpq_gettext("authentication method %u not supported\n"), areq);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
@ -587,6 +588,7 @@ fe_getauthname(char *PQerrormsg)
|
||||
const char *name = NULL;
|
||||
char *authn;
|
||||
MsgType authsvc;
|
||||
|
||||
#ifdef WIN32
|
||||
char username[128];
|
||||
DWORD namesize = sizeof(username) - 1;
|
||||
@ -623,7 +625,7 @@ fe_getauthname(char *PQerrormsg)
|
||||
|
||||
if (authsvc != STARTUP_MSG && authsvc != STARTUP_KRB5_MSG)
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
libpq_gettext("fe_getauthname: invalid authentication system: %d\n"),
|
||||
libpq_gettext("fe_getauthname: invalid authentication system: %d\n"),
|
||||
authsvc);
|
||||
|
||||
authn = name ? strdup(name) : NULL;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.h,v 1.21 2005/06/27 02:04:26 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.h,v 1.22 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -39,6 +39,6 @@ extern MsgType fe_getauthsvc(char *PQerrormsg);
|
||||
extern void fe_setauthsvc(const char *name, char *PQerrormsg);
|
||||
extern char *fe_getauthname(char *PQerrormsg);
|
||||
|
||||
#define PG_KRB5_VERSION "PGVER5.1" /* at most KRB_SENDAUTH_VLEN chars */
|
||||
#define PG_KRB5_VERSION "PGVER5.1" /* at most KRB_SENDAUTH_VLEN chars */
|
||||
|
||||
#endif /* FE_AUTH_H */
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.321 2005/09/26 17:49:09 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.322 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -116,9 +116,9 @@
|
||||
*/
|
||||
static const PQconninfoOption PQconninfoOptions[] = {
|
||||
/*
|
||||
* "authtype" is no longer used, so mark it "don't show". We keep it
|
||||
* in the array so as not to reject conninfo strings from old apps
|
||||
* that might still try to set it.
|
||||
* "authtype" is no longer used, so mark it "don't show". We keep it in
|
||||
* the array so as not to reject conninfo strings from old apps that might
|
||||
* still try to set it.
|
||||
*/
|
||||
{"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
|
||||
"Database-Authtype", "D", 20},
|
||||
@ -168,8 +168,8 @@ static const PQconninfoOption PQconninfoOptions[] = {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "sslmode" option is allowed even without client SSL support because
|
||||
* the client can still handle SSL modes "disable" and "allow".
|
||||
* "sslmode" option is allowed even without client SSL support because the
|
||||
* client can still handle SSL modes "disable" and "allow".
|
||||
*/
|
||||
{"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
|
||||
"SSL-Mode", "", 8}, /* sizeof("disable") == 8 */
|
||||
@ -177,7 +177,7 @@ static const PQconninfoOption PQconninfoOptions[] = {
|
||||
#ifdef KRB5
|
||||
/* Kerberos authentication supports specifying the service name */
|
||||
{"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
|
||||
"Kerberos-service-name", "", 20},
|
||||
"Kerberos-service-name", "", 20},
|
||||
#endif
|
||||
|
||||
/* Terminating entry --- MUST BE LAST */
|
||||
@ -370,8 +370,8 @@ connectOptions1(PGconn *conn, const char *conninfo)
|
||||
/*
|
||||
* Move option values into conn structure
|
||||
*
|
||||
* Don't put anything cute here --- intelligence should be in
|
||||
* connectOptions2 ...
|
||||
* Don't put anything cute here --- intelligence should be in connectOptions2
|
||||
* ...
|
||||
*
|
||||
* XXX: probably worth checking strdup() return value here...
|
||||
*/
|
||||
@ -476,7 +476,7 @@ connectOptions2(PGconn *conn)
|
||||
{
|
||||
conn->status = CONNECTION_BAD;
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("invalid sslmode value: \"%s\"\n"),
|
||||
libpq_gettext("invalid sslmode value: \"%s\"\n"),
|
||||
conn->sslmode);
|
||||
return false;
|
||||
}
|
||||
@ -488,8 +488,8 @@ connectOptions2(PGconn *conn)
|
||||
case 'p': /* "prefer" */
|
||||
|
||||
/*
|
||||
* warn user that an SSL connection will never be
|
||||
* negotiated since SSL was not compiled in?
|
||||
* warn user that an SSL connection will never be negotiated
|
||||
* since SSL was not compiled in?
|
||||
*/
|
||||
break;
|
||||
|
||||
@ -655,8 +655,8 @@ connectNoDelay(PGconn *conn)
|
||||
char sebuf[256];
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -686,9 +686,9 @@ connectFailureMessage(PGconn *conn, int errorno)
|
||||
NI_NUMERICSERV);
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"could not connect to server: %s\n"
|
||||
"\tIs the server running locally and accepting\n"
|
||||
"\tconnections on Unix domain socket \"%s\"?\n"
|
||||
"could not connect to server: %s\n"
|
||||
"\tIs the server running locally and accepting\n"
|
||||
"\tconnections on Unix domain socket \"%s\"?\n"
|
||||
),
|
||||
SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
|
||||
service);
|
||||
@ -698,9 +698,9 @@ connectFailureMessage(PGconn *conn, int errorno)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"could not connect to server: %s\n"
|
||||
"\tIs the server running on host \"%s\" and accepting\n"
|
||||
"\tTCP/IP connections on port %s?\n"
|
||||
"could not connect to server: %s\n"
|
||||
"\tIs the server running on host \"%s\" and accepting\n"
|
||||
"\tTCP/IP connections on port %s?\n"
|
||||
),
|
||||
SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
|
||||
conn->pghostaddr
|
||||
@ -815,12 +815,11 @@ connectDBStart(PGconn *conn)
|
||||
conn->status = CONNECTION_NEEDED;
|
||||
|
||||
/*
|
||||
* The code for processing CONNECTION_NEEDED state is in
|
||||
* PQconnectPoll(), so that it can easily be re-executed if needed
|
||||
* again during the asynchronous startup process. However, we must
|
||||
* run it once here, because callers expect a success return from this
|
||||
* routine to mean that we are in PGRES_POLLING_WRITING connection
|
||||
* state.
|
||||
* The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
|
||||
* so that it can easily be re-executed if needed again during the
|
||||
* asynchronous startup process. However, we must run it once here,
|
||||
* because callers expect a success return from this routine to mean that
|
||||
* we are in PGRES_POLLING_WRITING connection state.
|
||||
*/
|
||||
if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
|
||||
return 1;
|
||||
@ -863,8 +862,7 @@ connectDBComplete(PGconn *conn)
|
||||
if (timeout > 0)
|
||||
{
|
||||
/*
|
||||
* Rounding could cause connection to fail; need at least 2
|
||||
* secs
|
||||
* Rounding could cause connection to fail; need at least 2 secs
|
||||
*/
|
||||
if (timeout < 2)
|
||||
timeout = 2;
|
||||
@ -877,8 +875,7 @@ connectDBComplete(PGconn *conn)
|
||||
{
|
||||
/*
|
||||
* Wait, if necessary. Note that the initial state (just after
|
||||
* PQconnectStart) is to wait for the socket to select for
|
||||
* writing.
|
||||
* PQconnectStart) is to wait for the socket to select for writing.
|
||||
*/
|
||||
switch (flag)
|
||||
{
|
||||
@ -954,8 +951,8 @@ PQconnectPoll(PGconn *conn)
|
||||
switch (conn->status)
|
||||
{
|
||||
/*
|
||||
* We really shouldn't have been polled in these two cases,
|
||||
* but we can handle it.
|
||||
* We really shouldn't have been polled in these two cases, but we
|
||||
* can handle it.
|
||||
*/
|
||||
case CONNECTION_BAD:
|
||||
return PGRES_POLLING_FAILED;
|
||||
@ -995,24 +992,24 @@ PQconnectPoll(PGconn *conn)
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"invalid connection state, "
|
||||
"probably indicative of memory corruption\n"
|
||||
"probably indicative of memory corruption\n"
|
||||
));
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
|
||||
keep_going: /* We will come back to here until there
|
||||
* is nothing left to do. */
|
||||
keep_going: /* We will come back to here until there is
|
||||
* nothing left to do. */
|
||||
switch (conn->status)
|
||||
{
|
||||
case CONNECTION_NEEDED:
|
||||
{
|
||||
/*
|
||||
* Try to initiate a connection to one of the addresses
|
||||
* returned by getaddrinfo_all(). conn->addr_cur is the
|
||||
* next one to try. We fail when we run out of addresses
|
||||
* (reporting the error returned for the *last*
|
||||
* alternative, which may not be what users expect :-().
|
||||
* returned by getaddrinfo_all(). conn->addr_cur is the next
|
||||
* one to try. We fail when we run out of addresses
|
||||
* (reporting the error returned for the *last* alternative,
|
||||
* which may not be what users expect :-().
|
||||
*/
|
||||
while (conn->addr_cur != NULL)
|
||||
{
|
||||
@ -1028,8 +1025,8 @@ keep_going: /* We will come back to here until there
|
||||
if (conn->sock < 0)
|
||||
{
|
||||
/*
|
||||
* ignore socket() failure if we have more
|
||||
* addresses to try
|
||||
* ignore socket() failure if we have more addresses
|
||||
* to try
|
||||
*/
|
||||
if (addr_cur->ai_next != NULL)
|
||||
{
|
||||
@ -1037,15 +1034,15 @@ keep_going: /* We will come back to here until there
|
||||
continue;
|
||||
}
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not create socket: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not create socket: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select socket options: no delay of outgoing data
|
||||
* for TCP sockets, nonblock mode, close-on-exec.
|
||||
* Fail if any of this fails.
|
||||
* Select socket options: no delay of outgoing data for
|
||||
* TCP sockets, nonblock mode, close-on-exec. Fail if any
|
||||
* of this fails.
|
||||
*/
|
||||
if (!IS_AF_UNIX(addr_cur->ai_family))
|
||||
{
|
||||
@ -1061,7 +1058,7 @@ keep_going: /* We will come back to here until there
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not set socket to non-blocking mode: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
closesocket(conn->sock);
|
||||
conn->sock = -1;
|
||||
conn->addr_cur = addr_cur->ai_next;
|
||||
@ -1073,18 +1070,17 @@ keep_going: /* We will come back to here until there
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
closesocket(conn->sock);
|
||||
conn->sock = -1;
|
||||
conn->addr_cur = addr_cur->ai_next;
|
||||
continue;
|
||||
}
|
||||
#endif /* F_SETFD */
|
||||
#endif /* F_SETFD */
|
||||
|
||||
/*
|
||||
* Start/make connection. This should not block,
|
||||
* since we are in nonblock mode. If it does, well,
|
||||
* too bad.
|
||||
* Start/make connection. This should not block, since we
|
||||
* are in nonblock mode. If it does, well, too bad.
|
||||
*/
|
||||
if (connect(conn->sock, addr_cur->ai_addr,
|
||||
addr_cur->ai_addrlen) < 0)
|
||||
@ -1095,9 +1091,9 @@ keep_going: /* We will come back to here until there
|
||||
SOCK_ERRNO == 0)
|
||||
{
|
||||
/*
|
||||
* This is fine - we're in non-blocking mode,
|
||||
* and the connection is in progress. Tell
|
||||
* caller to wait for write-ready on socket.
|
||||
* This is fine - we're in non-blocking mode, and
|
||||
* the connection is in progress. Tell caller to
|
||||
* wait for write-ready on socket.
|
||||
*/
|
||||
conn->status = CONNECTION_STARTED;
|
||||
return PGRES_POLLING_WRITING;
|
||||
@ -1107,20 +1103,19 @@ keep_going: /* We will come back to here until there
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Hm, we're connected already --- seems the
|
||||
* "nonblock connection" wasn't. Advance the
|
||||
* state machine and go do the next stuff.
|
||||
* Hm, we're connected already --- seems the "nonblock
|
||||
* connection" wasn't. Advance the state machine and
|
||||
* go do the next stuff.
|
||||
*/
|
||||
conn->status = CONNECTION_STARTED;
|
||||
goto keep_going;
|
||||
}
|
||||
|
||||
/*
|
||||
* This connection failed --- set up error report,
|
||||
* then close socket (do it this way in case close()
|
||||
* affects the value of errno...). We will ignore the
|
||||
* connect() failure and keep going if there are more
|
||||
* addresses.
|
||||
* This connection failed --- set up error report, then
|
||||
* close socket (do it this way in case close() affects
|
||||
* the value of errno...). We will ignore the connect()
|
||||
* failure and keep going if there are more addresses.
|
||||
*/
|
||||
connectFailureMessage(conn, SOCK_ERRNO);
|
||||
if (conn->sock >= 0)
|
||||
@ -1136,8 +1131,8 @@ keep_going: /* We will come back to here until there
|
||||
} /* loop over addresses */
|
||||
|
||||
/*
|
||||
* Ooops, no more addresses. An appropriate error message
|
||||
* is already set up, so just set the right status.
|
||||
* Ooops, no more addresses. An appropriate error message is
|
||||
* already set up, so just set the right status.
|
||||
*/
|
||||
goto error_return;
|
||||
}
|
||||
@ -1148,8 +1143,8 @@ keep_going: /* We will come back to here until there
|
||||
ACCEPT_TYPE_ARG3 optlen = sizeof(optval);
|
||||
|
||||
/*
|
||||
* Write ready, since we've made it here, so the
|
||||
* connection has been made ... or has failed.
|
||||
* Write ready, since we've made it here, so the connection
|
||||
* has been made ... or has failed.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1161,23 +1156,22 @@ keep_going: /* We will come back to here until there
|
||||
(char *) &optval, &optlen) == -1)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not get socket error status: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not get socket error status: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
goto error_return;
|
||||
}
|
||||
else if (optval != 0)
|
||||
{
|
||||
/*
|
||||
* When using a nonblocking connect, we will typically
|
||||
* see connect failures at this point, so provide a
|
||||
* friendly error message.
|
||||
* When using a nonblocking connect, we will typically see
|
||||
* connect failures at this point, so provide a friendly
|
||||
* error message.
|
||||
*/
|
||||
connectFailureMessage(conn, optval);
|
||||
|
||||
/*
|
||||
* If more addresses remain, keep trying, just as in
|
||||
* the case where connect() returned failure
|
||||
* immediately.
|
||||
* If more addresses remain, keep trying, just as in the
|
||||
* case where connect() returned failure immediately.
|
||||
*/
|
||||
if (conn->addr_cur->ai_next != NULL)
|
||||
{
|
||||
@ -1201,7 +1195,7 @@ keep_going: /* We will come back to here until there
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not get client address from socket: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
@ -1220,9 +1214,8 @@ keep_going: /* We will come back to here until there
|
||||
#ifdef USE_SSL
|
||||
|
||||
/*
|
||||
* If SSL is enabled and we haven't already got it
|
||||
* running, request it instead of sending the startup
|
||||
* message.
|
||||
* If SSL is enabled and we haven't already got it running,
|
||||
* request it instead of sending the startup message.
|
||||
*/
|
||||
if (IS_AF_UNIX(conn->raddr.addr.ss_family))
|
||||
{
|
||||
@ -1237,16 +1230,15 @@ keep_going: /* We will come back to here until there
|
||||
/*
|
||||
* Send the SSL request packet.
|
||||
*
|
||||
* Theoretically, this could block, but it really
|
||||
* shouldn't since we only got here if the socket is
|
||||
* write-ready.
|
||||
* Theoretically, this could block, but it really shouldn't
|
||||
* since we only got here if the socket is write-ready.
|
||||
*/
|
||||
pv = htonl(NEGOTIATE_SSL_CODE);
|
||||
if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not send SSL negotiation packet: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
goto error_return;
|
||||
}
|
||||
/* Ok, wait for response */
|
||||
@ -1260,10 +1252,10 @@ keep_going: /* We will come back to here until there
|
||||
*/
|
||||
if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
|
||||
startpacket = pqBuildStartupPacket3(conn, &packetlen,
|
||||
EnvironmentOptions);
|
||||
EnvironmentOptions);
|
||||
else
|
||||
startpacket = pqBuildStartupPacket2(conn, &packetlen,
|
||||
EnvironmentOptions);
|
||||
EnvironmentOptions);
|
||||
if (!startpacket)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
@ -1274,14 +1266,14 @@ keep_going: /* We will come back to here until there
|
||||
/*
|
||||
* Send the startup packet.
|
||||
*
|
||||
* Theoretically, this could block, but it really shouldn't
|
||||
* since we only got here if the socket is write-ready.
|
||||
* Theoretically, this could block, but it really shouldn't since
|
||||
* we only got here if the socket is write-ready.
|
||||
*/
|
||||
if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not send startup packet: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not send startup packet: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
free(startpacket);
|
||||
goto error_return;
|
||||
}
|
||||
@ -1302,15 +1294,15 @@ keep_going: /* We will come back to here until there
|
||||
PostgresPollingStatusType pollres;
|
||||
|
||||
/*
|
||||
* On first time through, get the postmaster's response to
|
||||
* our SSL negotiation packet.
|
||||
* On first time through, get the postmaster's response to our
|
||||
* SSL negotiation packet.
|
||||
*/
|
||||
if (conn->ssl == NULL)
|
||||
{
|
||||
/*
|
||||
* We use pqReadData here since it has the logic to
|
||||
* distinguish no-data-yet from connection closure.
|
||||
* Since conn->ssl isn't set, a plain recv() will occur.
|
||||
* distinguish no-data-yet from connection closure. Since
|
||||
* conn->ssl isn't set, a plain recv() will occur.
|
||||
*/
|
||||
char SSLok;
|
||||
int rdresult;
|
||||
@ -1402,8 +1394,8 @@ keep_going: /* We will come back to here until there
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle authentication exchange: wait for postmaster
|
||||
* messages and respond as necessary.
|
||||
* Handle authentication exchange: wait for postmaster messages
|
||||
* and respond as necessary.
|
||||
*/
|
||||
case CONNECTION_AWAITING_RESPONSE:
|
||||
{
|
||||
@ -1413,9 +1405,9 @@ keep_going: /* We will come back to here until there
|
||||
AuthRequest areq;
|
||||
|
||||
/*
|
||||
* Scan the message from current point (note that if we
|
||||
* find the message is incomplete, we will return without
|
||||
* advancing inStart, and resume here next time).
|
||||
* Scan the message from current point (note that if we find
|
||||
* the message is incomplete, we will return without advancing
|
||||
* inStart, and resume here next time).
|
||||
*/
|
||||
conn->inCursor = conn->inStart;
|
||||
|
||||
@ -1435,8 +1427,8 @@ keep_going: /* We will come back to here until there
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"expected authentication request from "
|
||||
"server, but received %c\n"),
|
||||
"expected authentication request from "
|
||||
"server, but received %c\n"),
|
||||
beresp);
|
||||
goto error_return;
|
||||
}
|
||||
@ -1458,17 +1450,17 @@ keep_going: /* We will come back to here until there
|
||||
|
||||
/*
|
||||
* Try to validate message length before using it.
|
||||
* Authentication requests can't be very large. Errors
|
||||
* can be a little larger, but not huge. If we see a
|
||||
* large apparent length in an error, it means we're
|
||||
* really talking to a pre-3.0-protocol server; cope.
|
||||
* Authentication requests can't be very large. Errors can be
|
||||
* a little larger, but not huge. If we see a large apparent
|
||||
* length in an error, it means we're really talking to a
|
||||
* pre-3.0-protocol server; cope.
|
||||
*/
|
||||
if (beresp == 'R' && (msgLength < 8 || msgLength > 100))
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"expected authentication request from "
|
||||
"server, but received %c\n"),
|
||||
"expected authentication request from "
|
||||
"server, but received %c\n"),
|
||||
beresp);
|
||||
goto error_return;
|
||||
}
|
||||
@ -1486,9 +1478,8 @@ keep_going: /* We will come back to here until there
|
||||
conn->inStart = conn->inCursor;
|
||||
|
||||
/*
|
||||
* The postmaster typically won't end its message with
|
||||
* a newline, so add one to conform to libpq
|
||||
* conventions.
|
||||
* The postmaster typically won't end its message with a
|
||||
* newline, so add one to conform to libpq conventions.
|
||||
*/
|
||||
appendPQExpBufferChar(&conn->errorMessage, '\n');
|
||||
|
||||
@ -1513,16 +1504,16 @@ keep_going: /* We will come back to here until there
|
||||
/*
|
||||
* Can't process if message body isn't all here yet.
|
||||
*
|
||||
* (In protocol 2.0 case, we are assuming messages carry at
|
||||
* least 4 bytes of data.)
|
||||
* (In protocol 2.0 case, we are assuming messages carry at least
|
||||
* 4 bytes of data.)
|
||||
*/
|
||||
msgLength -= 4;
|
||||
avail = conn->inEnd - conn->inCursor;
|
||||
if (avail < msgLength)
|
||||
{
|
||||
/*
|
||||
* Before returning, try to enlarge the input buffer
|
||||
* if needed to hold the whole message; see notes in
|
||||
* Before returning, try to enlarge the input buffer if
|
||||
* needed to hold the whole message; see notes in
|
||||
* pqParseInput3.
|
||||
*/
|
||||
if (pqCheckInBufferSpace(conn->inCursor + msgLength, conn))
|
||||
@ -1557,8 +1548,7 @@ keep_going: /* We will come back to here until there
|
||||
|
||||
/*
|
||||
* if sslmode is "allow" and we haven't tried an SSL
|
||||
* connection already, then retry with an SSL
|
||||
* connection
|
||||
* connection already, then retry with an SSL connection
|
||||
*/
|
||||
if (conn->sslmode[0] == 'a' /* "allow" */
|
||||
&& conn->ssl == NULL
|
||||
@ -1575,8 +1565,8 @@ keep_going: /* We will come back to here until there
|
||||
}
|
||||
|
||||
/*
|
||||
* if sslmode is "prefer" and we're in an SSL
|
||||
* connection, then do a non-SSL retry
|
||||
* if sslmode is "prefer" and we're in an SSL connection,
|
||||
* then do a non-SSL retry
|
||||
*/
|
||||
if (conn->sslmode[0] == 'p' /* "prefer" */
|
||||
&& conn->ssl
|
||||
@ -1626,21 +1616,20 @@ keep_going: /* We will come back to here until there
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we successfully read the message; mark data
|
||||
* consumed
|
||||
* OK, we successfully read the message; mark data consumed
|
||||
*/
|
||||
conn->inStart = conn->inCursor;
|
||||
|
||||
/* Respond to the request if necessary. */
|
||||
|
||||
/*
|
||||
* Note that conn->pghost must be non-NULL if we are going
|
||||
* to avoid the Kerberos code doing a hostname look-up.
|
||||
* Note that conn->pghost must be non-NULL if we are going to
|
||||
* avoid the Kerberos code doing a hostname look-up.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX fe-auth.c has not been fixed to support
|
||||
* PQExpBuffers, so:
|
||||
* XXX fe-auth.c has not been fixed to support PQExpBuffers,
|
||||
* so:
|
||||
*/
|
||||
if (fe_sendauth(areq, conn, conn->pghost, conn->pgpass,
|
||||
conn->errorMessage.data) != STATUS_OK)
|
||||
@ -1651,10 +1640,9 @@ keep_going: /* We will come back to here until there
|
||||
conn->errorMessage.len = strlen(conn->errorMessage.data);
|
||||
|
||||
/*
|
||||
* Just make sure that any data sent by fe_sendauth is
|
||||
* flushed out. Although this theoretically could block,
|
||||
* it really shouldn't since we don't send large auth
|
||||
* responses.
|
||||
* Just make sure that any data sent by fe_sendauth is flushed
|
||||
* out. Although this theoretically could block, it really
|
||||
* shouldn't since we don't send large auth responses.
|
||||
*/
|
||||
if (pqFlush(conn))
|
||||
goto error_return;
|
||||
@ -1680,14 +1668,14 @@ keep_going: /* We will come back to here until there
|
||||
{
|
||||
/*
|
||||
* Now we expect to hear from the backend. A ReadyForQuery
|
||||
* message indicates that startup is successful, but we
|
||||
* might also get an Error message indicating failure.
|
||||
* (Notice messages indicating nonfatal warnings are also
|
||||
* allowed by the protocol, as are ParameterStatus and
|
||||
* BackendKeyData messages.) Easiest way to handle this is
|
||||
* to let PQgetResult() read the messages. We just have to
|
||||
* fake it out about the state of the connection, by
|
||||
* setting asyncStatus = PGASYNC_BUSY (done above).
|
||||
* message indicates that startup is successful, but we might
|
||||
* also get an Error message indicating failure. (Notice
|
||||
* messages indicating nonfatal warnings are also allowed by
|
||||
* the protocol, as are ParameterStatus and BackendKeyData
|
||||
* messages.) Easiest way to handle this is to let
|
||||
* PQgetResult() read the messages. We just have to fake it
|
||||
* out about the state of the connection, by setting
|
||||
* asyncStatus = PGASYNC_BUSY (done above).
|
||||
*/
|
||||
|
||||
if (PQisBusy(conn))
|
||||
@ -1706,11 +1694,10 @@ keep_going: /* We will come back to here until there
|
||||
libpq_gettext("unexpected message from server during startup\n"));
|
||||
|
||||
/*
|
||||
* if the resultStatus is FATAL, then
|
||||
* conn->errorMessage already has a copy of the error;
|
||||
* needn't copy it back. But add a newline if it's not
|
||||
* there already, since postmaster error messages may
|
||||
* not have one.
|
||||
* if the resultStatus is FATAL, then conn->errorMessage
|
||||
* already has a copy of the error; needn't copy it back.
|
||||
* But add a newline if it's not there already, since
|
||||
* postmaster error messages may not have one.
|
||||
*/
|
||||
if (conn->errorMessage.len <= 0 ||
|
||||
conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
|
||||
@ -1741,8 +1728,7 @@ keep_going: /* We will come back to here until there
|
||||
case CONNECTION_SETENV:
|
||||
|
||||
/*
|
||||
* Do post-connection housekeeping (only needed in protocol
|
||||
* 2.0).
|
||||
* Do post-connection housekeeping (only needed in protocol 2.0).
|
||||
*
|
||||
* We pretend that the connection is OK for the duration of these
|
||||
* queries.
|
||||
@ -1773,8 +1759,8 @@ keep_going: /* We will come back to here until there
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"invalid connection state %c, "
|
||||
"probably indicative of memory corruption\n"
|
||||
"invalid connection state %c, "
|
||||
"probably indicative of memory corruption\n"
|
||||
),
|
||||
conn->status);
|
||||
goto error_return;
|
||||
@ -1785,11 +1771,11 @@ keep_going: /* We will come back to here until there
|
||||
error_return:
|
||||
|
||||
/*
|
||||
* We used to close the socket at this point, but that makes it
|
||||
* awkward for those above us if they wish to remove this socket from
|
||||
* their own records (an fd_set for example). We'll just have this
|
||||
* socket closed when PQfinish is called (which is compulsory even
|
||||
* after an error, since the connection structure must be freed).
|
||||
* We used to close the socket at this point, but that makes it awkward
|
||||
* for those above us if they wish to remove this socket from their own
|
||||
* records (an fd_set for example). We'll just have this socket closed
|
||||
* when PQfinish is called (which is compulsory even after an error, since
|
||||
* the connection structure must be freed).
|
||||
*/
|
||||
conn->status = CONNECTION_BAD;
|
||||
return PGRES_POLLING_FAILED;
|
||||
@ -1806,11 +1792,11 @@ makeEmptyPGconn(void)
|
||||
PGconn *conn;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
* Make sure socket support is up and running.
|
||||
* Even though this is done in libpqdll.c, that is only for MSVC and
|
||||
* BCC builds and doesn't work for static builds at all, so we have
|
||||
* to do it in the main code too.
|
||||
* Make sure socket support is up and running. Even though this is done in
|
||||
* libpqdll.c, that is only for MSVC and BCC builds and doesn't work for
|
||||
* static builds at all, so we have to do it in the main code too.
|
||||
*/
|
||||
WSADATA wsaData;
|
||||
|
||||
@ -1841,15 +1827,15 @@ makeEmptyPGconn(void)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We try to send at least 8K at a time, which is the usual size of
|
||||
* pipe buffers on Unix systems. That way, when we are sending a
|
||||
* large amount of data, we avoid incurring extra kernel context swaps
|
||||
* for partial bufferloads. The output buffer is initially made 16K
|
||||
* in size, and we try to dump it after accumulating 8K.
|
||||
* We try to send at least 8K at a time, which is the usual size of pipe
|
||||
* buffers on Unix systems. That way, when we are sending a large amount
|
||||
* of data, we avoid incurring extra kernel context swaps for partial
|
||||
* bufferloads. The output buffer is initially made 16K in size, and we
|
||||
* try to dump it after accumulating 8K.
|
||||
*
|
||||
* With the same goal of minimizing context swaps, the input buffer will
|
||||
* be enlarged anytime it has less than 8K free, so we initially
|
||||
* allocate twice that.
|
||||
* With the same goal of minimizing context swaps, the input buffer will be
|
||||
* enlarged anytime it has less than 8K free, so we initially allocate
|
||||
* twice that.
|
||||
*/
|
||||
conn->inBufSize = 16 * 1024;
|
||||
conn->inBuffer = (char *) malloc(conn->inBufSize);
|
||||
@ -1928,7 +1914,7 @@ freePGconn(PGconn *conn)
|
||||
notify = conn->notifyHead;
|
||||
while (notify != NULL)
|
||||
{
|
||||
PGnotify *prev = notify;
|
||||
PGnotify *prev = notify;
|
||||
|
||||
notify = notify->next;
|
||||
free(prev);
|
||||
@ -1980,9 +1966,9 @@ closePGconn(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* must reset the blocking status so a possible reconnect will work
|
||||
* don't call PQsetnonblocking() because it will fail if it's unable
|
||||
* to flush the connection.
|
||||
* must reset the blocking status so a possible reconnect will work don't
|
||||
* call PQsetnonblocking() because it will fail if it's unable to flush
|
||||
* the connection.
|
||||
*/
|
||||
conn->nonblocking = FALSE;
|
||||
|
||||
@ -2005,7 +1991,7 @@ closePGconn(PGconn *conn)
|
||||
notify = conn->notifyHead;
|
||||
while (notify != NULL)
|
||||
{
|
||||
PGnotify *prev = notify;
|
||||
PGnotify *prev = notify;
|
||||
|
||||
notify = notify->next;
|
||||
free(prev);
|
||||
@ -2104,7 +2090,7 @@ PQresetPoll(PGconn *conn)
|
||||
PGcancel *
|
||||
PQgetCancel(PGconn *conn)
|
||||
{
|
||||
PGcancel *cancel;
|
||||
PGcancel *cancel;
|
||||
|
||||
if (!conn)
|
||||
return NULL;
|
||||
@ -2159,7 +2145,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
|
||||
int save_errno = SOCK_ERRNO;
|
||||
int tmpsock = -1;
|
||||
char sebuf[256];
|
||||
int maxlen;
|
||||
int maxlen;
|
||||
struct
|
||||
{
|
||||
uint32 packetlen;
|
||||
@ -2167,8 +2153,8 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
|
||||
} crp;
|
||||
|
||||
/*
|
||||
* We need to open a temporary connection to the postmaster. Do
|
||||
* this with only kernel calls.
|
||||
* We need to open a temporary connection to the postmaster. Do this with
|
||||
* only kernel calls.
|
||||
*/
|
||||
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
@ -2208,12 +2194,11 @@ retry4:
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the postmaster to close the connection, which indicates
|
||||
* that it's processed the request. Without this delay, we might
|
||||
* issue another command only to find that our cancel zaps that
|
||||
* command instead of the one we thought we were canceling. Note we
|
||||
* don't actually expect this read to obtain any data, we are just
|
||||
* waiting for EOF to be signaled.
|
||||
* Wait for the postmaster to close the connection, which indicates that
|
||||
* it's processed the request. Without this delay, we might issue another
|
||||
* command only to find that our cancel zaps that command instead of the
|
||||
* one we thought we were canceling. Note we don't actually expect this
|
||||
* read to obtain any data, we are just waiting for EOF to be signaled.
|
||||
*/
|
||||
retry5:
|
||||
if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
|
||||
@ -2230,9 +2215,10 @@ retry5:
|
||||
return TRUE;
|
||||
|
||||
cancel_errReturn:
|
||||
|
||||
/*
|
||||
* Make sure we don't overflow the error buffer. Leave space for
|
||||
* the \n at the end, and for the terminating zero.
|
||||
* Make sure we don't overflow the error buffer. Leave space for the \n at
|
||||
* the end, and for the terminating zero.
|
||||
*/
|
||||
maxlen = errbufsize - strlen(errbuf) - 2;
|
||||
if (maxlen >= 0)
|
||||
@ -2253,7 +2239,7 @@ cancel_errReturn:
|
||||
* Returns TRUE if able to send the cancel request, FALSE if not.
|
||||
*
|
||||
* On failure, an error message is stored in *errbuf, which must be of size
|
||||
* errbufsize (recommended size is 256 bytes). *errbuf is not changed on
|
||||
* errbufsize (recommended size is 256 bytes). *errbuf is not changed on
|
||||
* success return.
|
||||
*/
|
||||
int
|
||||
@ -2284,7 +2270,7 @@ PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
|
||||
int
|
||||
PQrequestCancel(PGconn *conn)
|
||||
{
|
||||
int r;
|
||||
int r;
|
||||
|
||||
/* Check we have an open connection */
|
||||
if (!conn)
|
||||
@ -2362,9 +2348,9 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
||||
i;
|
||||
|
||||
/*
|
||||
* We have to special-case the environment variable PGSERVICE here,
|
||||
* since this is and should be called before inserting environment
|
||||
* defaults for other connection options.
|
||||
* We have to special-case the environment variable PGSERVICE here, since
|
||||
* this is and should be called before inserting environment defaults for
|
||||
* other connection options.
|
||||
*/
|
||||
if (service == NULL)
|
||||
service = getenv("PGSERVICE");
|
||||
@ -2398,7 +2384,7 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
||||
{
|
||||
fclose(f);
|
||||
printfPQExpBuffer(errorMessage,
|
||||
libpq_gettext("ERROR: line %d too long in service file \"%s\"\n"),
|
||||
libpq_gettext("ERROR: line %d too long in service file \"%s\"\n"),
|
||||
linenr,
|
||||
serviceFile);
|
||||
return 2;
|
||||
@ -2437,8 +2423,8 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
||||
if (group_found)
|
||||
{
|
||||
/*
|
||||
* Finally, we are in the right group and can parse
|
||||
* the line
|
||||
* Finally, we are in the right group and can parse the
|
||||
* line
|
||||
*/
|
||||
char *key,
|
||||
*val;
|
||||
@ -2458,8 +2444,8 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
||||
*val++ = '\0';
|
||||
|
||||
/*
|
||||
* Set the parameter --- but don't override any
|
||||
* previous explicit setting.
|
||||
* Set the parameter --- but don't override any previous
|
||||
* explicit setting.
|
||||
*/
|
||||
found_keyword = false;
|
||||
for (i = 0; options[i].keyword; i++)
|
||||
@ -2638,8 +2624,7 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have the name and the value. Search for the param
|
||||
* record.
|
||||
* Now we have the name and the value. Search for the param record.
|
||||
*/
|
||||
for (option = options; option->keyword != NULL; option++)
|
||||
{
|
||||
@ -2649,7 +2634,7 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
|
||||
if (option->keyword == NULL)
|
||||
{
|
||||
printfPQExpBuffer(errorMessage,
|
||||
libpq_gettext("invalid connection option \"%s\"\n"),
|
||||
libpq_gettext("invalid connection option \"%s\"\n"),
|
||||
pname);
|
||||
PQconninfoFree(options);
|
||||
free(buf);
|
||||
@ -2676,8 +2661,8 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
|
||||
free(buf);
|
||||
|
||||
/*
|
||||
* If there's a service spec, use it to obtain any
|
||||
* not-explicitly-given parameters.
|
||||
* If there's a service spec, use it to obtain any not-explicitly-given
|
||||
* parameters.
|
||||
*/
|
||||
if (parseServiceInfo(options, errorMessage))
|
||||
{
|
||||
@ -2686,8 +2671,8 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the fallback resources for parameters not specified in the
|
||||
* conninfo string nor the service.
|
||||
* Get the fallback resources for parameters not specified in the conninfo
|
||||
* string nor the service.
|
||||
*/
|
||||
for (option = options; option->keyword != NULL; option++)
|
||||
{
|
||||
@ -3100,7 +3085,7 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
|
||||
FILE *fp;
|
||||
char pgpassfile[MAXPGPATH];
|
||||
struct stat stat_buf;
|
||||
char *passfile_env;
|
||||
char *passfile_env;
|
||||
|
||||
#define LINELEN NAMEDATALEN*5
|
||||
char buf[LINELEN];
|
||||
@ -3138,7 +3123,7 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
|
||||
if (!S_ISREG(stat_buf.st_mode))
|
||||
{
|
||||
fprintf(stderr,
|
||||
libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
|
||||
libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
|
||||
pgpassfile);
|
||||
free(pgpassfile);
|
||||
return NULL;
|
||||
@ -3212,7 +3197,6 @@ pqGetHomeDirectory(char *buf, int bufsize)
|
||||
return false;
|
||||
StrNCpy(buf, pwd->pw_dir, bufsize);
|
||||
return true;
|
||||
|
||||
#else
|
||||
char tmppath[MAX_PATH];
|
||||
|
||||
@ -3235,7 +3219,6 @@ default_threadlock(int acquire)
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
#ifndef WIN32
|
||||
static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#else
|
||||
static pthread_mutex_t singlethread_lock = NULL;
|
||||
static long mutex_initlock = 0;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.175 2005/09/24 17:53:28 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.176 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -30,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
/* keep this in same order as ExecStatusType in libpq-fe.h */
|
||||
char *const pgresStatus[] = {
|
||||
char *const pgresStatus[] = {
|
||||
"PGRES_EMPTY_QUERY",
|
||||
"PGRES_COMMAND_OK",
|
||||
"PGRES_TUPLES_OK",
|
||||
@ -209,8 +209,8 @@ pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
|
||||
return res->null_field;
|
||||
|
||||
/*
|
||||
* If alignment is needed, round up the current position to an
|
||||
* alignment boundary.
|
||||
* If alignment is needed, round up the current position to an alignment
|
||||
* boundary.
|
||||
*/
|
||||
if (isBinary)
|
||||
{
|
||||
@ -234,10 +234,9 @@ pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
|
||||
|
||||
/*
|
||||
* If the requested object is very large, give it its own block; this
|
||||
* avoids wasting what might be most of the current block to start a
|
||||
* new block. (We'd have to special-case requests bigger than the
|
||||
* block size anyway.) The object is always given binary alignment in
|
||||
* this case.
|
||||
* avoids wasting what might be most of the current block to start a new
|
||||
* block. (We'd have to special-case requests bigger than the block size
|
||||
* anyway.) The object is always given binary alignment in this case.
|
||||
*/
|
||||
if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
|
||||
{
|
||||
@ -393,8 +392,8 @@ void
|
||||
pqSaveErrorResult(PGconn *conn)
|
||||
{
|
||||
/*
|
||||
* If no old async result, just let PQmakeEmptyPGresult make one.
|
||||
* Likewise if old result is not an error message.
|
||||
* If no old async result, just let PQmakeEmptyPGresult make one. Likewise
|
||||
* if old result is not an error message.
|
||||
*/
|
||||
if (conn->result == NULL ||
|
||||
conn->result->resultStatus != PGRES_FATAL_ERROR ||
|
||||
@ -423,9 +422,9 @@ pqPrepareAsyncResult(PGconn *conn)
|
||||
PGresult *res;
|
||||
|
||||
/*
|
||||
* conn->result is the PGresult to return. If it is NULL (which
|
||||
* probably shouldn't happen) we assume there is an appropriate error
|
||||
* message in conn->errorMessage.
|
||||
* conn->result is the PGresult to return. If it is NULL (which probably
|
||||
* shouldn't happen) we assume there is an appropriate error message in
|
||||
* conn->errorMessage.
|
||||
*/
|
||||
res = conn->result;
|
||||
conn->result = NULL; /* handing over ownership to caller */
|
||||
@ -435,8 +434,8 @@ pqPrepareAsyncResult(PGconn *conn)
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Make sure PQerrorMessage agrees with result; it could be
|
||||
* different if we have concatenated messages.
|
||||
* Make sure PQerrorMessage agrees with result; it could be different
|
||||
* if we have concatenated messages.
|
||||
*/
|
||||
resetPQExpBuffer(&conn->errorMessage);
|
||||
appendPQExpBufferStr(&conn->errorMessage,
|
||||
@ -455,7 +454,7 @@ pqPrepareAsyncResult(PGconn *conn)
|
||||
* a trailing newline, and should not be more than one line).
|
||||
*/
|
||||
void
|
||||
pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt, ...)
|
||||
pqInternalNotice(const PGNoticeHooks * hooks, const char *fmt,...)
|
||||
{
|
||||
char msgBuf[1024];
|
||||
va_list args;
|
||||
@ -484,8 +483,8 @@ pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt, ...)
|
||||
/* XXX should provide a SQLSTATE too? */
|
||||
|
||||
/*
|
||||
* Result text is always just the primary message + newline. If we
|
||||
* can't allocate it, don't bother invoking the receiver.
|
||||
* Result text is always just the primary message + newline. If we can't
|
||||
* allocate it, don't bother invoking the receiver.
|
||||
*/
|
||||
res->errMsg = (char *) pqResultAlloc(res, strlen(msgBuf) + 2, FALSE);
|
||||
if (res->errMsg)
|
||||
@ -506,20 +505,20 @@ pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt, ...)
|
||||
* Returns TRUE if OK, FALSE if not enough memory to add the row
|
||||
*/
|
||||
int
|
||||
pqAddTuple(PGresult *res, PGresAttValue *tup)
|
||||
pqAddTuple(PGresult *res, PGresAttValue * tup)
|
||||
{
|
||||
if (res->ntups >= res->tupArrSize)
|
||||
{
|
||||
/*
|
||||
* Try to grow the array.
|
||||
*
|
||||
* We can use realloc because shallow copying of the structure is
|
||||
* okay. Note that the first time through, res->tuples is NULL.
|
||||
* While ANSI says that realloc() should act like malloc() in that
|
||||
* case, some old C libraries (like SunOS 4.1.x) coredump instead.
|
||||
* On failure realloc is supposed to return NULL without damaging
|
||||
* the existing allocation. Note that the positions beyond
|
||||
* res->ntups are garbage, not necessarily NULL.
|
||||
* We can use realloc because shallow copying of the structure is okay.
|
||||
* Note that the first time through, res->tuples is NULL. While ANSI
|
||||
* says that realloc() should act like malloc() in that case, some old
|
||||
* C libraries (like SunOS 4.1.x) coredump instead. On failure realloc
|
||||
* is supposed to return NULL without damaging the existing
|
||||
* allocation. Note that the positions beyond res->ntups are garbage,
|
||||
* not necessarily NULL.
|
||||
*/
|
||||
int newSize = (res->tupArrSize > 0) ? res->tupArrSize * 2 : 128;
|
||||
PGresAttValue **newTuples;
|
||||
@ -595,7 +594,7 @@ pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
|
||||
* Store new info as a single malloc block
|
||||
*/
|
||||
pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +
|
||||
strlen(name) +strlen(value) + 2);
|
||||
strlen(name) + strlen(value) + 2);
|
||||
if (pstatus)
|
||||
{
|
||||
char *ptr;
|
||||
@ -611,8 +610,8 @@ pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
|
||||
}
|
||||
|
||||
/*
|
||||
* Special hacks: remember client_encoding as a numeric value, and
|
||||
* convert server version to a numeric form as well.
|
||||
* Special hacks: remember client_encoding as a numeric value, and convert
|
||||
* server version to a numeric form as well.
|
||||
*/
|
||||
if (strcmp(name, "client_encoding") == 0)
|
||||
conn->client_encoding = pg_char_to_encoding(value);
|
||||
@ -653,7 +652,7 @@ PQsendQuery(PGconn *conn, const char *query)
|
||||
if (!query)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("command string is a null pointer\n"));
|
||||
libpq_gettext("command string is a null pointer\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -670,9 +669,8 @@ PQsendQuery(PGconn *conn, const char *query)
|
||||
conn->queryclass = PGQUERY_SIMPLE;
|
||||
|
||||
/*
|
||||
* Give the data a push. In nonblock mode, don't complain if we're
|
||||
* unable to send it all; PQgetResult() will do any additional
|
||||
* flushing needed.
|
||||
* Give the data a push. In nonblock mode, don't complain if we're unable
|
||||
* to send it all; PQgetResult() will do any additional flushing needed.
|
||||
*/
|
||||
if (pqFlush(conn) < 0)
|
||||
{
|
||||
@ -705,7 +703,7 @@ PQsendQueryParams(PGconn *conn,
|
||||
if (!command)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("command string is a null pointer\n"));
|
||||
libpq_gettext("command string is a null pointer\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -722,10 +720,10 @@ PQsendQueryParams(PGconn *conn,
|
||||
|
||||
/*
|
||||
* PQsendPrepare
|
||||
* Submit a Parse message, but don't wait for it to finish
|
||||
* Submit a Parse message, but don't wait for it to finish
|
||||
*
|
||||
* Returns: 1 if successfully submitted
|
||||
* 0 if error (conn->errorMessage is set)
|
||||
* 0 if error (conn->errorMessage is set)
|
||||
*/
|
||||
int
|
||||
PQsendPrepare(PGconn *conn,
|
||||
@ -738,14 +736,14 @@ PQsendPrepare(PGconn *conn,
|
||||
if (!stmtName)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("statement name is a null pointer\n"));
|
||||
libpq_gettext("statement name is a null pointer\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!query)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("command string is a null pointer\n"));
|
||||
libpq_gettext("command string is a null pointer\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -753,7 +751,7 @@ PQsendPrepare(PGconn *conn,
|
||||
if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("function requires at least protocol version 3.0\n"));
|
||||
libpq_gettext("function requires at least protocol version 3.0\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -765,7 +763,7 @@ PQsendPrepare(PGconn *conn,
|
||||
|
||||
if (nParams > 0 && paramTypes)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (pqPutInt(nParams, 2, conn) < 0)
|
||||
goto sendFailed;
|
||||
@ -792,9 +790,8 @@ PQsendPrepare(PGconn *conn,
|
||||
conn->queryclass = PGQUERY_PREPARE;
|
||||
|
||||
/*
|
||||
* Give the data a push. In nonblock mode, don't complain if we're
|
||||
* unable to send it all; PQgetResult() will do any additional
|
||||
* flushing needed.
|
||||
* Give the data a push. In nonblock mode, don't complain if we're unable
|
||||
* to send it all; PQgetResult() will do any additional flushing needed.
|
||||
*/
|
||||
if (pqFlush(conn) < 0)
|
||||
goto sendFailed;
|
||||
@ -828,7 +825,7 @@ PQsendQueryPrepared(PGconn *conn,
|
||||
if (!stmtName)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("statement name is a null pointer\n"));
|
||||
libpq_gettext("statement name is a null pointer\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -866,7 +863,7 @@ PQsendQueryStart(PGconn *conn)
|
||||
if (conn->asyncStatus != PGASYNC_IDLE)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("another command is already in progress\n"));
|
||||
libpq_gettext("another command is already in progress\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -902,13 +899,13 @@ PQsendQueryGuts(PGconn *conn,
|
||||
if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("function requires at least protocol version 3.0\n"));
|
||||
libpq_gettext("function requires at least protocol version 3.0\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We will send Parse (if needed), Bind, Describe Portal, Execute,
|
||||
* Sync, using specified statement name and the unnamed portal.
|
||||
* We will send Parse (if needed), Bind, Describe Portal, Execute, Sync,
|
||||
* using specified statement name and the unnamed portal.
|
||||
*/
|
||||
|
||||
if (command)
|
||||
@ -1022,9 +1019,8 @@ PQsendQueryGuts(PGconn *conn,
|
||||
conn->queryclass = PGQUERY_EXTENDED;
|
||||
|
||||
/*
|
||||
* Give the data a push. In nonblock mode, don't complain if we're
|
||||
* unable to send it all; PQgetResult() will do any additional
|
||||
* flushing needed.
|
||||
* Give the data a push. In nonblock mode, don't complain if we're unable
|
||||
* to send it all; PQgetResult() will do any additional flushing needed.
|
||||
*/
|
||||
if (pqFlush(conn) < 0)
|
||||
goto sendFailed;
|
||||
@ -1051,8 +1047,8 @@ pqHandleSendFailure(PGconn *conn)
|
||||
{
|
||||
/*
|
||||
* Accept any available input data, ignoring errors. Note that if
|
||||
* pqReadData decides the backend has closed the channel, it will
|
||||
* close our side of the socket --- that's just what we want here.
|
||||
* pqReadData decides the backend has closed the channel, it will close
|
||||
* our side of the socket --- that's just what we want here.
|
||||
*/
|
||||
while (pqReadData(conn) > 0)
|
||||
/* loop until no more data readable */ ;
|
||||
@ -1076,9 +1072,9 @@ PQconsumeInput(PGconn *conn)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* for non-blocking connections try to flush the send-queue, otherwise
|
||||
* we may never get a response for something that may not have already
|
||||
* been sent because it's in our write buffer!
|
||||
* for non-blocking connections try to flush the send-queue, otherwise we
|
||||
* may never get a response for something that may not have already been
|
||||
* sent because it's in our write buffer!
|
||||
*/
|
||||
if (pqIsnonblocking(conn))
|
||||
{
|
||||
@ -1087,10 +1083,10 @@ PQconsumeInput(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* Load more data, if available. We do this no matter what state we
|
||||
* are in, since we are probably getting called because the
|
||||
* application wants to get rid of a read-select condition. Note that
|
||||
* we will NOT block waiting for more input.
|
||||
* Load more data, if available. We do this no matter what state we are
|
||||
* in, since we are probably getting called because the application wants
|
||||
* to get rid of a read-select condition. Note that we will NOT block
|
||||
* waiting for more input.
|
||||
*/
|
||||
if (pqReadData(conn) < 0)
|
||||
return 0;
|
||||
@ -1157,8 +1153,8 @@ PQgetResult(PGconn *conn)
|
||||
int flushResult;
|
||||
|
||||
/*
|
||||
* If data remains unsent, send it. Else we might be waiting for
|
||||
* the result of a command the backend hasn't even got yet.
|
||||
* If data remains unsent, send it. Else we might be waiting for the
|
||||
* result of a command the backend hasn't even got yet.
|
||||
*/
|
||||
while ((flushResult = pqFlush(conn)) > 0)
|
||||
{
|
||||
@ -1212,7 +1208,7 @@ PQgetResult(PGconn *conn)
|
||||
break;
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("unexpected asyncStatus: %d\n"),
|
||||
libpq_gettext("unexpected asyncStatus: %d\n"),
|
||||
(int) conn->asyncStatus);
|
||||
res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
|
||||
break;
|
||||
@ -1268,7 +1264,7 @@ PQexecParams(PGconn *conn,
|
||||
|
||||
/*
|
||||
* PQprepare
|
||||
* Creates a prepared statement by issuing a v3.0 parse message.
|
||||
* Creates a prepared statement by issuing a v3.0 parse message.
|
||||
*
|
||||
* If the query was not even sent, return NULL; conn->errorMessage is set to
|
||||
* a relevant message.
|
||||
@ -1324,9 +1320,8 @@ PQexecStart(PGconn *conn)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Silently discard any prior query result that application didn't
|
||||
* eat. This is probably poor design, but it's here for backward
|
||||
* compatibility.
|
||||
* Silently discard any prior query result that application didn't eat.
|
||||
* This is probably poor design, but it's here for backward compatibility.
|
||||
*/
|
||||
while ((result = PQgetResult(conn)) != NULL)
|
||||
{
|
||||
@ -1339,7 +1334,7 @@ PQexecStart(PGconn *conn)
|
||||
{
|
||||
/* In protocol 3, we can get out of a COPY IN state */
|
||||
if (PQputCopyEnd(conn,
|
||||
libpq_gettext("COPY terminated by new PQexec")) < 0)
|
||||
libpq_gettext("COPY terminated by new PQexec")) < 0)
|
||||
return false;
|
||||
/* keep waiting to swallow the copy's failure message */
|
||||
}
|
||||
@ -1347,7 +1342,7 @@ PQexecStart(PGconn *conn)
|
||||
{
|
||||
/* In older protocols we have to punt */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("COPY IN state must be terminated first\n"));
|
||||
libpq_gettext("COPY IN state must be terminated first\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1356,9 +1351,9 @@ PQexecStart(PGconn *conn)
|
||||
if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
|
||||
{
|
||||
/*
|
||||
* In protocol 3, we can get out of a COPY OUT state: we
|
||||
* just switch back to BUSY and allow the remaining COPY
|
||||
* data to be dropped on the floor.
|
||||
* In protocol 3, we can get out of a COPY OUT state: we just
|
||||
* switch back to BUSY and allow the remaining COPY data to be
|
||||
* dropped on the floor.
|
||||
*/
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
/* keep waiting to swallow the copy's completion message */
|
||||
@ -1367,7 +1362,7 @@ PQexecStart(PGconn *conn)
|
||||
{
|
||||
/* In older protocols we have to punt */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("COPY OUT state must be terminated first\n"));
|
||||
libpq_gettext("COPY OUT state must be terminated first\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1390,9 +1385,9 @@ PQexecFinish(PGconn *conn)
|
||||
PGresult *lastResult;
|
||||
|
||||
/*
|
||||
* For backwards compatibility, return the last result if there are
|
||||
* more than one --- but merge error messages if we get more than one
|
||||
* error result.
|
||||
* For backwards compatibility, return the last result if there are more
|
||||
* than one --- but merge error messages if we get more than one error
|
||||
* result.
|
||||
*
|
||||
* We have to stop if we see copy in/out, however. We will resume parsing
|
||||
* after application performs the data transfer.
|
||||
@ -1412,8 +1407,7 @@ PQexecFinish(PGconn *conn)
|
||||
result = lastResult;
|
||||
|
||||
/*
|
||||
* Make sure PQerrorMessage agrees with concatenated
|
||||
* result
|
||||
* Make sure PQerrorMessage agrees with concatenated result
|
||||
*/
|
||||
resetPQExpBuffer(&conn->errorMessage);
|
||||
appendPQExpBufferStr(&conn->errorMessage, result->errMsg);
|
||||
@ -1494,11 +1488,11 @@ PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
|
||||
if (nbytes > 0)
|
||||
{
|
||||
/*
|
||||
* Try to flush any previously sent data in preference to growing
|
||||
* the output buffer. If we can't enlarge the buffer enough to
|
||||
* hold the data, return 0 in the nonblock case, else hard error.
|
||||
* (For simplicity, always assume 5 bytes of overhead even in
|
||||
* protocol 2.0 case.)
|
||||
* Try to flush any previously sent data in preference to growing the
|
||||
* output buffer. If we can't enlarge the buffer enough to hold the
|
||||
* data, return 0 in the nonblock case, else hard error. (For
|
||||
* simplicity, always assume 5 bytes of overhead even in protocol 2.0
|
||||
* case.)
|
||||
*/
|
||||
if ((conn->outBufSize - conn->outCount - 5) < nbytes)
|
||||
{
|
||||
@ -1569,8 +1563,8 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
|
||||
}
|
||||
|
||||
/*
|
||||
* If we sent the COPY command in extended-query mode, we must
|
||||
* issue a Sync as well.
|
||||
* If we sent the COPY command in extended-query mode, we must issue a
|
||||
* Sync as well.
|
||||
*/
|
||||
if (conn->queryclass != PGQUERY_SIMPLE)
|
||||
{
|
||||
@ -1982,8 +1976,8 @@ PQfnumber(const PGresult *res, const char *field_name)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Note: it is correct to reject a zero-length input string; the
|
||||
* proper input to match a zero-length field name would be "".
|
||||
* Note: it is correct to reject a zero-length input string; the proper
|
||||
* input to match a zero-length field name would be "".
|
||||
*/
|
||||
if (field_name == NULL ||
|
||||
field_name[0] == '\0' ||
|
||||
@ -1992,8 +1986,8 @@ PQfnumber(const PGresult *res, const char *field_name)
|
||||
|
||||
/*
|
||||
* Note: this code will not reject partially quoted strings, eg
|
||||
* foo"BAR"foo will become fooBARfoo when it probably ought to be an
|
||||
* error condition.
|
||||
* foo"BAR"foo will become fooBARfoo when it probably ought to be an error
|
||||
* condition.
|
||||
*/
|
||||
field_case = strdup(field_name);
|
||||
if (field_case == NULL)
|
||||
@ -2156,11 +2150,11 @@ PQoidValue(const PGresult *res)
|
||||
char *endptr = NULL;
|
||||
unsigned long result;
|
||||
|
||||
if (!res ||
|
||||
!res->cmdStatus ||
|
||||
strncmp(res->cmdStatus, "INSERT ", 7) != 0 ||
|
||||
res->cmdStatus[7] < '0' ||
|
||||
res->cmdStatus[7] > '9')
|
||||
if (!res ||
|
||||
!res->cmdStatus ||
|
||||
strncmp(res->cmdStatus, "INSERT ", 7) != 0 ||
|
||||
res->cmdStatus[7] < '0' ||
|
||||
res->cmdStatus[7] > '9')
|
||||
return InvalidOid;
|
||||
|
||||
result = strtoul(res->cmdStatus + 7, &endptr, 10);
|
||||
@ -2280,11 +2274,10 @@ PQsetnonblocking(PGconn *conn, int arg)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* to guarantee constancy for flushing/query/result-polling behavior
|
||||
* we need to flush the send queue at this point in order to guarantee
|
||||
* proper behavior. this is ok because either they are making a
|
||||
* transition _from_ or _to_ blocking mode, either way we can block
|
||||
* them.
|
||||
* to guarantee constancy for flushing/query/result-polling behavior we
|
||||
* need to flush the send queue at this point in order to guarantee proper
|
||||
* behavior. this is ok because either they are making a transition _from_
|
||||
* or _to_ blocking mode, either way we can block them.
|
||||
*/
|
||||
/* if we are going from blocking to non-blocking flush here */
|
||||
if (pqFlush(conn))
|
||||
@ -2519,9 +2512,9 @@ PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
|
||||
/*
|
||||
* Note: if we see '\' followed by something that isn't a
|
||||
* recognized escape sequence, we loop around having done
|
||||
* nothing except advance i. Therefore the something will
|
||||
* be emitted as ordinary data on the next cycle. Corner
|
||||
* case: '\' at end of string will just be discarded.
|
||||
* nothing except advance i. Therefore the something will be
|
||||
* emitted as ordinary data on the next cycle. Corner case:
|
||||
* '\' at end of string will just be discarded.
|
||||
*/
|
||||
break;
|
||||
|
||||
@ -2530,8 +2523,7 @@ PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
buflen = j; /* buflen is the length of the dequoted
|
||||
* data */
|
||||
buflen = j; /* buflen is the length of the dequoted data */
|
||||
|
||||
/* Shrink the buffer to be no larger than necessary */
|
||||
/* +1 avoids unportable behavior when buflen==0 */
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.53 2005/06/13 02:26:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.54 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -328,7 +328,7 @@ lo_create(PGconn *conn, Oid lobjId)
|
||||
if (conn->lobjfuncs->fn_lo_create == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_create\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_create\n"));
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
@ -453,8 +453,8 @@ lo_import(PGconn *conn, const char *filename)
|
||||
char sebuf[256];
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not open file \"%s\": %s\n"),
|
||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not open file \"%s\": %s\n"),
|
||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ lo_import(PGconn *conn, const char *filename)
|
||||
if (lobjOid == InvalidOid)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not create large object for file \"%s\"\n"),
|
||||
libpq_gettext("could not create large object for file \"%s\"\n"),
|
||||
filename);
|
||||
(void) close(fd);
|
||||
return InvalidOid;
|
||||
@ -475,7 +475,7 @@ lo_import(PGconn *conn, const char *filename)
|
||||
if (lobj == -1)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not open large object %u\n"),
|
||||
libpq_gettext("could not open large object %u\n"),
|
||||
lobjOid);
|
||||
(void) close(fd);
|
||||
return InvalidOid;
|
||||
@ -490,7 +490,7 @@ lo_import(PGconn *conn, const char *filename)
|
||||
if (tmp < nbytes)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("error while reading file \"%s\"\n"),
|
||||
libpq_gettext("error while reading file \"%s\"\n"),
|
||||
filename);
|
||||
(void) close(fd);
|
||||
(void) lo_close(conn, lobj);
|
||||
@ -525,7 +525,7 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
||||
if (lobj == -1)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not open large object %u\n"), lobjId);
|
||||
libpq_gettext("could not open large object %u\n"), lobjId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -538,8 +538,8 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
||||
char sebuf[256];
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not open file \"%s\": %s\n"),
|
||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not open file \"%s\": %s\n"),
|
||||
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
(void) lo_close(conn, lobj);
|
||||
return -1;
|
||||
}
|
||||
@ -553,7 +553,7 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
||||
if (tmp < nbytes)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("error while writing to file \"%s\"\n"),
|
||||
libpq_gettext("error while writing to file \"%s\"\n"),
|
||||
filename);
|
||||
(void) lo_close(conn, lobj);
|
||||
(void) close(fd);
|
||||
@ -566,7 +566,7 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
|
||||
if (close(fd))
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("error while writing to file \"%s\"\n"),
|
||||
libpq_gettext("error while writing to file \"%s\"\n"),
|
||||
filename);
|
||||
return -1;
|
||||
}
|
||||
@ -605,9 +605,8 @@ lo_initialize(PGconn *conn)
|
||||
MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
|
||||
|
||||
/*
|
||||
* Execute the query to get all the functions at once. In 7.3 and
|
||||
* later we need to be schema-safe. lo_create only exists in 8.1
|
||||
* and up.
|
||||
* Execute the query to get all the functions at once. In 7.3 and later
|
||||
* we need to be schema-safe. lo_create only exists in 8.1 and up.
|
||||
*/
|
||||
if (conn->sversion >= 70300)
|
||||
query = "select proname, oid from pg_catalog.pg_proc "
|
||||
@ -680,62 +679,62 @@ lo_initialize(PGconn *conn)
|
||||
PQclear(res);
|
||||
|
||||
/*
|
||||
* Finally check that we really got all large object interface
|
||||
* functions --- except lo_create, which may not exist.
|
||||
* Finally check that we really got all large object interface functions
|
||||
* --- except lo_create, which may not exist.
|
||||
*/
|
||||
if (lobjfuncs->fn_lo_open == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_open\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_open\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_close == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_close\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_close\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_creat == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_creat\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_creat\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_unlink == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_unlink\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_unlink\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_lseek == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_lseek\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_lseek\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_tell == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lo_tell\n"));
|
||||
libpq_gettext("cannot determine OID of function lo_tell\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_read == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function loread\n"));
|
||||
libpq_gettext("cannot determine OID of function loread\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_write == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("cannot determine OID of function lowrite\n"));
|
||||
libpq_gettext("cannot determine OID of function lowrite\n"));
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.121 2005/09/26 17:49:09 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.122 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -226,7 +226,7 @@ pqGetInt(int *result, size_t bytes, PGconn *conn)
|
||||
break;
|
||||
default:
|
||||
pqInternalNotice(&conn->noticeHooks,
|
||||
"integer of size %lu not supported by pqGetInt",
|
||||
"integer of size %lu not supported by pqGetInt",
|
||||
(unsigned long) bytes);
|
||||
return EOF;
|
||||
}
|
||||
@ -262,7 +262,7 @@ pqPutInt(int value, size_t bytes, PGconn *conn)
|
||||
break;
|
||||
default:
|
||||
pqInternalNotice(&conn->noticeHooks,
|
||||
"integer of size %lu not supported by pqPutInt",
|
||||
"integer of size %lu not supported by pqPutInt",
|
||||
(unsigned long) bytes);
|
||||
return EOF;
|
||||
}
|
||||
@ -289,9 +289,9 @@ pqCheckOutBufferSpace(int bytes_needed, PGconn *conn)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If we need to enlarge the buffer, we first try to double it in
|
||||
* size; if that doesn't work, enlarge in multiples of 8K. This
|
||||
* avoids thrashing the malloc pool by repeated small enlargements.
|
||||
* If we need to enlarge the buffer, we first try to double it in size; if
|
||||
* that doesn't work, enlarge in multiples of 8K. This avoids thrashing
|
||||
* the malloc pool by repeated small enlargements.
|
||||
*
|
||||
* Note: tests for newsize > 0 are to catch integer overflow.
|
||||
*/
|
||||
@ -352,9 +352,9 @@ pqCheckInBufferSpace(int bytes_needed, PGconn *conn)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If we need to enlarge the buffer, we first try to double it in
|
||||
* size; if that doesn't work, enlarge in multiples of 8K. This
|
||||
* avoids thrashing the malloc pool by repeated small enlargements.
|
||||
* If we need to enlarge the buffer, we first try to double it in size; if
|
||||
* that doesn't work, enlarge in multiples of 8K. This avoids thrashing
|
||||
* the malloc pool by repeated small enlargements.
|
||||
*
|
||||
* Note: tests for newsize > 0 are to catch integer overflow.
|
||||
*/
|
||||
@ -565,20 +565,19 @@ pqReadData(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the buffer is fairly full, enlarge it. We need to be able to
|
||||
* enlarge the buffer in case a single message exceeds the initial
|
||||
* buffer size. We enlarge before filling the buffer entirely so as
|
||||
* to avoid asking the kernel for a partial packet. The magic constant
|
||||
* here should be large enough for a TCP packet or Unix pipe
|
||||
* bufferload. 8K is the usual pipe buffer size, so...
|
||||
* If the buffer is fairly full, enlarge it. We need to be able to enlarge
|
||||
* the buffer in case a single message exceeds the initial buffer size.
|
||||
* We enlarge before filling the buffer entirely so as to avoid asking the
|
||||
* kernel for a partial packet. The magic constant here should be large
|
||||
* enough for a TCP packet or Unix pipe bufferload. 8K is the usual pipe
|
||||
* buffer size, so...
|
||||
*/
|
||||
if (conn->inBufSize - conn->inEnd < 8192)
|
||||
{
|
||||
if (pqCheckInBufferSpace(conn->inEnd + 8192, conn))
|
||||
{
|
||||
/*
|
||||
* We don't insist that the enlarge worked, but we need some
|
||||
* room
|
||||
* We don't insist that the enlarge worked, but we need some room
|
||||
*/
|
||||
if (conn->inBufSize - conn->inEnd < 100)
|
||||
return -1; /* errorMessage already set */
|
||||
@ -608,8 +607,8 @@ retry3:
|
||||
goto definitelyFailed;
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not receive data from server: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not receive data from server: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
return -1;
|
||||
}
|
||||
if (nread > 0)
|
||||
@ -617,17 +616,16 @@ retry3:
|
||||
conn->inEnd += nread;
|
||||
|
||||
/*
|
||||
* Hack to deal with the fact that some kernels will only give us
|
||||
* back 1 packet per recv() call, even if we asked for more and
|
||||
* there is more available. If it looks like we are reading a
|
||||
* long message, loop back to recv() again immediately, until we
|
||||
* run out of data or buffer space. Without this, the
|
||||
* block-and-restart behavior of libpq's higher levels leads to
|
||||
* O(N^2) performance on long messages.
|
||||
* Hack to deal with the fact that some kernels will only give us back
|
||||
* 1 packet per recv() call, even if we asked for more and there is
|
||||
* more available. If it looks like we are reading a long message,
|
||||
* loop back to recv() again immediately, until we run out of data or
|
||||
* buffer space. Without this, the block-and-restart behavior of
|
||||
* libpq's higher levels leads to O(N^2) performance on long messages.
|
||||
*
|
||||
* Since we left-justified the data above, conn->inEnd gives the
|
||||
* amount of data already read in the current message. We
|
||||
* consider the message "long" once we have acquired 32k ...
|
||||
* Since we left-justified the data above, conn->inEnd gives the amount
|
||||
* of data already read in the current message. We consider the
|
||||
* message "long" once we have acquired 32k ...
|
||||
*/
|
||||
if (conn->inEnd > 32768 &&
|
||||
(conn->inBufSize - conn->inEnd) >= 8192)
|
||||
@ -642,18 +640,18 @@ retry3:
|
||||
return 1; /* got a zero read after successful tries */
|
||||
|
||||
/*
|
||||
* A return value of 0 could mean just that no data is now available,
|
||||
* or it could mean EOF --- that is, the server has closed the
|
||||
* connection. Since we have the socket in nonblock mode, the only way
|
||||
* to tell the difference is to see if select() is saying that the
|
||||
* file is ready. Grumble. Fortunately, we don't expect this path to
|
||||
* be taken much, since in normal practice we should not be trying to
|
||||
* read data unless the file selected for reading already.
|
||||
* A return value of 0 could mean just that no data is now available, or
|
||||
* it could mean EOF --- that is, the server has closed the connection.
|
||||
* Since we have the socket in nonblock mode, the only way to tell the
|
||||
* difference is to see if select() is saying that the file is ready.
|
||||
* Grumble. Fortunately, we don't expect this path to be taken much,
|
||||
* since in normal practice we should not be trying to read data unless
|
||||
* the file selected for reading already.
|
||||
*
|
||||
* In SSL mode it's even worse: SSL_read() could say WANT_READ and then
|
||||
* data could arrive before we make the pqReadReady() test. So we
|
||||
* must play dumb and assume there is more data, relying on the SSL
|
||||
* layer to detect true EOF.
|
||||
* In SSL mode it's even worse: SSL_read() could say WANT_READ and then data
|
||||
* could arrive before we make the pqReadReady() test. So we must play
|
||||
* dumb and assume there is more data, relying on the SSL layer to detect
|
||||
* true EOF.
|
||||
*/
|
||||
|
||||
#ifdef USE_SSL
|
||||
@ -699,8 +697,8 @@ retry4:
|
||||
goto definitelyFailed;
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not receive data from server: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not receive data from server: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
return -1;
|
||||
}
|
||||
if (nread > 0)
|
||||
@ -710,15 +708,15 @@ retry4:
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we are getting a zero read even though select() says ready.
|
||||
* This means the connection has been closed. Cope.
|
||||
* OK, we are getting a zero read even though select() says ready. This
|
||||
* means the connection has been closed. Cope.
|
||||
*/
|
||||
definitelyFailed:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"server closed the connection unexpectedly\n"
|
||||
"\tThis probably means the server terminated abnormally\n"
|
||||
"\tbefore or while processing the request.\n"));
|
||||
"server closed the connection unexpectedly\n"
|
||||
"\tThis probably means the server terminated abnormally\n"
|
||||
"\tbefore or while processing the request.\n"));
|
||||
conn->status = CONNECTION_BAD; /* No more connection to backend */
|
||||
pqsecure_close(conn);
|
||||
closesocket(conn->sock);
|
||||
@ -761,9 +759,9 @@ pqSendSome(PGconn *conn, int len)
|
||||
if (sent < 0)
|
||||
{
|
||||
/*
|
||||
* Anything except EAGAIN/EWOULDBLOCK/EINTR is trouble. If
|
||||
* it's EPIPE or ECONNRESET, assume we've lost the backend
|
||||
* connection permanently.
|
||||
* Anything except EAGAIN/EWOULDBLOCK/EINTR is trouble. If it's
|
||||
* EPIPE or ECONNRESET, assume we've lost the backend connection
|
||||
* permanently.
|
||||
*/
|
||||
switch (SOCK_ERRNO)
|
||||
{
|
||||
@ -784,25 +782,25 @@ pqSendSome(PGconn *conn, int len)
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"server closed the connection unexpectedly\n"
|
||||
"\tThis probably means the server terminated abnormally\n"
|
||||
"\tbefore or while processing the request.\n"));
|
||||
"server closed the connection unexpectedly\n"
|
||||
"\tThis probably means the server terminated abnormally\n"
|
||||
"\tbefore or while processing the request.\n"));
|
||||
|
||||
/*
|
||||
* We used to close the socket here, but that's a bad
|
||||
* idea since there might be unread data waiting
|
||||
* (typically, a NOTICE message from the backend
|
||||
* telling us it's committing hara-kiri...). Leave
|
||||
* the socket open until pqReadData finds no more data
|
||||
* can be read. But abandon attempt to send data.
|
||||
* We used to close the socket here, but that's a bad idea
|
||||
* since there might be unread data waiting (typically, a
|
||||
* NOTICE message from the backend telling us it's
|
||||
* committing hara-kiri...). Leave the socket open until
|
||||
* pqReadData finds no more data can be read. But abandon
|
||||
* attempt to send data.
|
||||
*/
|
||||
conn->outCount = 0;
|
||||
return -1;
|
||||
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not send data to server: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("could not send data to server: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
/* We don't assume it's a fatal error... */
|
||||
conn->outCount = 0;
|
||||
return -1;
|
||||
@ -831,16 +829,15 @@ pqSendSome(PGconn *conn, int len)
|
||||
|
||||
/*
|
||||
* There are scenarios in which we can't send data because the
|
||||
* communications channel is full, but we cannot expect the
|
||||
* server to clear the channel eventually because it's blocked
|
||||
* trying to send data to us. (This can happen when we are
|
||||
* sending a large amount of COPY data, and the server has
|
||||
* generated lots of NOTICE responses.) To avoid a deadlock
|
||||
* situation, we must be prepared to accept and buffer
|
||||
* incoming data before we try again. Furthermore, it is
|
||||
* possible that such incoming data might not arrive until
|
||||
* after we've gone to sleep. Therefore, we wait for either
|
||||
* read ready or write ready.
|
||||
* communications channel is full, but we cannot expect the server
|
||||
* to clear the channel eventually because it's blocked trying to
|
||||
* send data to us. (This can happen when we are sending a large
|
||||
* amount of COPY data, and the server has generated lots of
|
||||
* NOTICE responses.) To avoid a deadlock situation, we must be
|
||||
* prepared to accept and buffer incoming data before we try
|
||||
* again. Furthermore, it is possible that such incoming data
|
||||
* might not arrive until after we've gone to sleep. Therefore,
|
||||
* we wait for either read ready or write ready.
|
||||
*/
|
||||
if (pqReadData(conn) < 0)
|
||||
{
|
||||
@ -990,7 +987,7 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("select() failed: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1040,7 +1037,6 @@ pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
|
||||
}
|
||||
|
||||
return poll(&input_fd, 1, timeout_ms);
|
||||
|
||||
#else /* !HAVE_POLL */
|
||||
|
||||
fd_set input_mask;
|
||||
@ -1134,9 +1130,9 @@ libpq_gettext(const char *msgid)
|
||||
{
|
||||
/* dgettext() preserves errno, but bindtextdomain() doesn't */
|
||||
#ifdef WIN32
|
||||
int save_errno = GetLastError();
|
||||
int save_errno = GetLastError();
|
||||
#else
|
||||
int save_errno = errno;
|
||||
int save_errno = errno;
|
||||
#endif
|
||||
const char *ldir;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* didn't really belong there.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-print.c,v 1.63 2005/08/23 21:02:03 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-print.c,v 1.64 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -45,7 +45,7 @@ static void do_field(const PQprintOpt *po, const PGresult *res,
|
||||
unsigned char *fieldNotNum, int *fieldMax,
|
||||
const int fieldMaxLen, FILE *fout);
|
||||
static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,
|
||||
int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,
|
||||
int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,
|
||||
const int fs_len, const PGresult *res);
|
||||
static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
|
||||
unsigned char *fieldNotNum, int *fieldMax, char *border,
|
||||
@ -88,6 +88,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
int total_line_length = 0;
|
||||
int usePipe = 0;
|
||||
char *pagerenv;
|
||||
|
||||
#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
|
||||
sigset_t osigset;
|
||||
bool sigpipe_masked = false;
|
||||
@ -99,7 +100,6 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
|
||||
#ifdef TIOCGWINSZ
|
||||
struct winsize screen_size;
|
||||
|
||||
#else
|
||||
struct winsize
|
||||
{
|
||||
@ -156,8 +156,8 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
)
|
||||
{
|
||||
/*
|
||||
* If we think there'll be more than one screen of output, try
|
||||
* to pipe to the pager program.
|
||||
* If we think there'll be more than one screen of output, try to
|
||||
* pipe to the pager program.
|
||||
*/
|
||||
#ifdef TIOCGWINSZ
|
||||
if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
|
||||
@ -195,8 +195,8 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
sigpipe_masked = true;
|
||||
#else
|
||||
oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
else
|
||||
fout = stdout;
|
||||
@ -256,7 +256,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
{
|
||||
if (po->html3)
|
||||
fprintf(fout,
|
||||
"<table %s><caption align=high>%d</caption>\n",
|
||||
"<table %s><caption align=high>%d</caption>\n",
|
||||
po->tableOpt ? po->tableOpt : "", i);
|
||||
else
|
||||
fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
|
||||
@ -276,7 +276,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
{
|
||||
if (po->caption)
|
||||
fprintf(fout,
|
||||
"<table %s><caption align=high>%s</caption>\n",
|
||||
"<table %s><caption align=high>%s</caption>\n",
|
||||
po->tableOpt ? po->tableOpt : "",
|
||||
po->caption);
|
||||
else
|
||||
@ -284,7 +284,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
"<table %s><caption align=high>"
|
||||
"Retrieved %d rows * %d fields"
|
||||
"</caption>\n",
|
||||
po->tableOpt ? po->tableOpt : "", nTups, nFields);
|
||||
po->tableOpt ? po->tableOpt : "", nTups, nFields);
|
||||
}
|
||||
else
|
||||
fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
|
||||
@ -311,15 +311,15 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
|
||||
_pclose(fout);
|
||||
#else
|
||||
pclose(fout);
|
||||
|
||||
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
/* we can't easily verify if EPIPE occurred, so say it did */
|
||||
if (sigpipe_masked)
|
||||
pq_reset_sigpipe(&osigset, sigpipe_pending, true);
|
||||
#else
|
||||
pqsignal(SIGPIPE, oldsigpipehandler);
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
if (po->html3 && !po->expanded)
|
||||
fputs("</table>\n", fout);
|
||||
@ -380,9 +380,9 @@ do_field(const PQprintOpt *po, const PGresult *res,
|
||||
}
|
||||
|
||||
/*
|
||||
* Above loop will believe E in first column is numeric; also,
|
||||
* we insist on a digit in the last column for a numeric. This
|
||||
* test is still not bulletproof but it handles most cases.
|
||||
* Above loop will believe E in first column is numeric; also, we
|
||||
* insist on a digit in the last column for a numeric. This test
|
||||
* is still not bulletproof but it handles most cases.
|
||||
*/
|
||||
if (*pval == 'E' || *pval == 'e' ||
|
||||
!(ch >= '0' && ch <= '9'))
|
||||
@ -547,7 +547,7 @@ output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
|
||||
|
||||
if (po->html3)
|
||||
fprintf(fout, "<td align=%s>%s</td>",
|
||||
fieldNotNum[field_index] ? "left" : "right", p ? p : "");
|
||||
fieldNotNum[field_index] ? "left" : "right", p ? p : "");
|
||||
else
|
||||
{
|
||||
fprintf(fout,
|
||||
@ -678,8 +678,7 @@ PQprintTuples(const PGresult *res,
|
||||
FILE *fout, /* output stream */
|
||||
int PrintAttNames, /* print attribute names or not */
|
||||
int TerseOutput, /* delimiter bars or not? */
|
||||
int colWidth /* width of column, if 0, use variable
|
||||
* width */
|
||||
int colWidth /* width of column, if 0, use variable width */
|
||||
)
|
||||
{
|
||||
int nFields;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.18 2005/06/12 00:00:21 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.19 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -89,7 +89,7 @@ pqSetenvPoll(PGconn *conn)
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"invalid setenv state %c, "
|
||||
"probably indicative of memory corruption\n"
|
||||
"probably indicative of memory corruption\n"
|
||||
),
|
||||
conn->setenv_state);
|
||||
goto error_return;
|
||||
@ -104,8 +104,8 @@ pqSetenvPoll(PGconn *conn)
|
||||
{
|
||||
/*
|
||||
* Send SET commands for stuff directed by Environment
|
||||
* Options. Note: we assume that SET commands won't
|
||||
* start transaction blocks, even in a 7.3 server with
|
||||
* Options. Note: we assume that SET commands won't start
|
||||
* transaction blocks, even in a 7.3 server with
|
||||
* autocommit off.
|
||||
*/
|
||||
char setQuery[100]; /* note length limit in
|
||||
@ -125,7 +125,7 @@ pqSetenvPoll(PGconn *conn)
|
||||
conn->next_eo->pgName, val);
|
||||
#ifdef CONNECTDEBUG
|
||||
fprintf(stderr,
|
||||
"Use environment variable %s to send %s\n",
|
||||
"Use environment variable %s to send %s\n",
|
||||
conn->next_eo->envName, setQuery);
|
||||
#endif
|
||||
if (!PQsendQuery(conn, setQuery))
|
||||
@ -173,9 +173,9 @@ pqSetenvPoll(PGconn *conn)
|
||||
case SETENV_STATE_QUERY1_SEND:
|
||||
{
|
||||
/*
|
||||
* Issue query to get information we need. Here we
|
||||
* must use begin/commit in case autocommit is off by
|
||||
* default in a 7.3 server.
|
||||
* Issue query to get information we need. Here we must
|
||||
* use begin/commit in case autocommit is off by default
|
||||
* in a 7.3 server.
|
||||
*
|
||||
* Note: version() exists in all protocol-2.0-supporting
|
||||
* backends. In 7.3 it would be safer to write
|
||||
@ -227,8 +227,8 @@ pqSetenvPoll(PGconn *conn)
|
||||
val += 11;
|
||||
|
||||
/*
|
||||
* strip off platform part (scribbles on
|
||||
* result, naughty naughty)
|
||||
* strip off platform part (scribbles on result,
|
||||
* naughty naughty)
|
||||
*/
|
||||
ptr = strchr(val, ' ');
|
||||
if (ptr)
|
||||
@ -254,11 +254,11 @@ pqSetenvPoll(PGconn *conn)
|
||||
const char *query;
|
||||
|
||||
/*
|
||||
* pg_client_encoding does not exist in pre-7.2
|
||||
* servers. So we need to be prepared for an error
|
||||
* here. Do *not* start a transaction block, except
|
||||
* in 7.3 servers where we need to prevent
|
||||
* autocommit-off from starting a transaction anyway.
|
||||
* pg_client_encoding does not exist in pre-7.2 servers.
|
||||
* So we need to be prepared for an error here. Do *not*
|
||||
* start a transaction block, except in 7.3 servers where
|
||||
* we need to prevent autocommit-off from starting a
|
||||
* transaction anyway.
|
||||
*/
|
||||
if (conn->sversion >= 70300 &&
|
||||
conn->sversion < 70400)
|
||||
@ -295,16 +295,15 @@ pqSetenvPoll(PGconn *conn)
|
||||
{
|
||||
/* Extract client encoding and save it */
|
||||
val = PQgetvalue(res, 0, 0);
|
||||
if (val && *val) /* null should not happen,
|
||||
* but */
|
||||
if (val && *val) /* null should not happen, but */
|
||||
pqSaveParameterStatus(conn, "client_encoding",
|
||||
val);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Error: presumably function not available,
|
||||
* so use PGCLIENTENCODING or SQL_ASCII as the
|
||||
* Error: presumably function not available, so
|
||||
* use PGCLIENTENCODING or SQL_ASCII as the
|
||||
* fallback.
|
||||
*/
|
||||
val = getenv("PGCLIENTENCODING");
|
||||
@ -331,7 +330,7 @@ pqSetenvPoll(PGconn *conn)
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("invalid state %c, "
|
||||
"probably indicative of memory corruption\n"),
|
||||
"probably indicative of memory corruption\n"),
|
||||
conn->setenv_state);
|
||||
goto error_return;
|
||||
}
|
||||
@ -361,11 +360,10 @@ pqParseInput2(PGconn *conn)
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Quit if in COPY_OUT state: we expect raw data from the server
|
||||
* until PQendcopy is called. Don't try to parse it according to
|
||||
* the normal protocol. (This is bogus. The data lines ought to
|
||||
* be part of the protocol and have identifying leading
|
||||
* characters.)
|
||||
* Quit if in COPY_OUT state: we expect raw data from the server until
|
||||
* PQendcopy is called. Don't try to parse it according to the normal
|
||||
* protocol. (This is bogus. The data lines ought to be part of the
|
||||
* protocol and have identifying leading characters.)
|
||||
*/
|
||||
if (conn->asyncStatus == PGASYNC_COPY_OUT)
|
||||
return;
|
||||
@ -381,9 +379,9 @@ pqParseInput2(PGconn *conn)
|
||||
* NOTIFY and NOTICE messages can happen in any state besides COPY
|
||||
* OUT; always process them right away.
|
||||
*
|
||||
* Most other messages should only be processed while in BUSY state.
|
||||
* (In particular, in READY state we hold off further parsing
|
||||
* until the application collects the current PGresult.)
|
||||
* Most other messages should only be processed while in BUSY state. (In
|
||||
* particular, in READY state we hold off further parsing until the
|
||||
* application collects the current PGresult.)
|
||||
*
|
||||
* However, if the state is IDLE then we got trouble; we need to deal
|
||||
* with the unexpected message somehow.
|
||||
@ -407,10 +405,10 @@ pqParseInput2(PGconn *conn)
|
||||
/*
|
||||
* Unexpected message in IDLE state; need to recover somehow.
|
||||
* ERROR messages are displayed using the notice processor;
|
||||
* anything else is just dropped on the floor after displaying
|
||||
* a suitable warning notice. (An ERROR is very possibly the
|
||||
* backend telling us why it is about to close the connection,
|
||||
* so we don't want to just discard it...)
|
||||
* anything else is just dropped on the floor after displaying a
|
||||
* suitable warning notice. (An ERROR is very possibly the
|
||||
* backend telling us why it is about to close the connection, so
|
||||
* we don't want to just discard it...)
|
||||
*/
|
||||
if (id == 'E')
|
||||
{
|
||||
@ -420,7 +418,7 @@ pqParseInput2(PGconn *conn)
|
||||
else
|
||||
{
|
||||
pqInternalNotice(&conn->noticeHooks,
|
||||
"message type 0x%02x arrived from server while idle",
|
||||
"message type 0x%02x arrived from server while idle",
|
||||
id);
|
||||
/* Discard the unexpected message; good idea?? */
|
||||
conn->inStart = conn->inEnd;
|
||||
@ -440,7 +438,7 @@ pqParseInput2(PGconn *conn)
|
||||
if (conn->result == NULL)
|
||||
{
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_COMMAND_OK);
|
||||
PGRES_COMMAND_OK);
|
||||
if (!conn->result)
|
||||
return;
|
||||
}
|
||||
@ -467,15 +465,15 @@ pqParseInput2(PGconn *conn)
|
||||
id);
|
||||
if (conn->result == NULL)
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_EMPTY_QUERY);
|
||||
PGRES_EMPTY_QUERY);
|
||||
conn->asyncStatus = PGASYNC_READY;
|
||||
break;
|
||||
case 'K': /* secret key data from the backend */
|
||||
|
||||
/*
|
||||
* This is expected only during backend startup, but
|
||||
* it's just as easy to handle it as part of the main
|
||||
* loop. Save the data and continue processing.
|
||||
* This is expected only during backend startup, but it's
|
||||
* just as easy to handle it as part of the main loop.
|
||||
* Save the data and continue processing.
|
||||
*/
|
||||
if (pqGetInt(&(conn->be_pid), 4, conn))
|
||||
return;
|
||||
@ -487,8 +485,7 @@ pqParseInput2(PGconn *conn)
|
||||
return;
|
||||
/* We pretty much ignore this message type... */
|
||||
break;
|
||||
case 'T': /* row descriptions (start of query
|
||||
* results) */
|
||||
case 'T': /* row descriptions (start of query results) */
|
||||
if (conn->result == NULL)
|
||||
{
|
||||
/* First 'T' in a query sequence */
|
||||
@ -499,10 +496,10 @@ pqParseInput2(PGconn *conn)
|
||||
{
|
||||
/*
|
||||
* A new 'T' message is treated as the start of
|
||||
* another PGresult. (It is not clear that this
|
||||
* is really possible with the current backend.)
|
||||
* We stop parsing until the application accepts
|
||||
* the current result.
|
||||
* another PGresult. (It is not clear that this is
|
||||
* really possible with the current backend.) We stop
|
||||
* parsing until the application accepts the current
|
||||
* result.
|
||||
*/
|
||||
conn->asyncStatus = PGASYNC_READY;
|
||||
return;
|
||||
@ -679,8 +676,8 @@ getAnotherTuple(PGconn *conn, bool binary)
|
||||
MemSet(conn->curTuple, 0, nfields * sizeof(PGresAttValue));
|
||||
|
||||
/*
|
||||
* If it's binary, fix the column format indicators. We assume
|
||||
* the backend will consistently send either B or D, not a mix.
|
||||
* If it's binary, fix the column format indicators. We assume the
|
||||
* backend will consistently send either B or D, not a mix.
|
||||
*/
|
||||
if (binary)
|
||||
{
|
||||
@ -765,16 +762,16 @@ outOfMemory:
|
||||
/* Replace partially constructed result with an error result */
|
||||
|
||||
/*
|
||||
* we do NOT use pqSaveErrorResult() here, because of the likelihood
|
||||
* that there's not enough memory to concatenate messages...
|
||||
* we do NOT use pqSaveErrorResult() here, because of the likelihood that
|
||||
* there's not enough memory to concatenate messages...
|
||||
*/
|
||||
pqClearAsyncResult(conn);
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("out of memory for query result\n"));
|
||||
|
||||
/*
|
||||
* XXX: if PQmakeEmptyPGresult() fails, there's probably not much
|
||||
* we can do to recover...
|
||||
* XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
|
||||
* do to recover...
|
||||
*/
|
||||
conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
|
||||
conn->asyncStatus = PGASYNC_READY;
|
||||
@ -805,8 +802,8 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
|
||||
|
||||
/*
|
||||
* Since the message might be pretty long, we create a temporary
|
||||
* PQExpBuffer rather than using conn->workBuffer. workBuffer is
|
||||
* intended for stuff that is expected to be short.
|
||||
* PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
|
||||
* for stuff that is expected to be short.
|
||||
*/
|
||||
initPQExpBuffer(&workBuf);
|
||||
if (pqGets(&workBuf, conn))
|
||||
@ -826,12 +823,12 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
|
||||
goto failure;
|
||||
|
||||
/*
|
||||
* Break the message into fields. We can't do very much here, but we
|
||||
* can split the severity code off, and remove trailing newlines.
|
||||
* Also, we use the heuristic that the primary message extends only to
|
||||
* the first newline --- anything after that is detail message. (In
|
||||
* some cases it'd be better classed as hint, but we can hardly be
|
||||
* expected to guess that here.)
|
||||
* Break the message into fields. We can't do very much here, but we can
|
||||
* split the severity code off, and remove trailing newlines. Also, we use
|
||||
* the heuristic that the primary message extends only to the first
|
||||
* newline --- anything after that is detail message. (In some cases it'd
|
||||
* be better classed as hint, but we can hardly be expected to guess that
|
||||
* here.)
|
||||
*/
|
||||
while (workBuf.len > 0 && workBuf.data[workBuf.len - 1] == '\n')
|
||||
workBuf.data[--workBuf.len] = '\0';
|
||||
@ -867,8 +864,8 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
|
||||
|
||||
/*
|
||||
* Either save error as current async result, or just emit the notice.
|
||||
* Also, if it's an error and we were in a transaction block, assume
|
||||
* the server has now gone to error-in-transaction state.
|
||||
* Also, if it's an error and we were in a transaction block, assume the
|
||||
* server has now gone to error-in-transaction state.
|
||||
*/
|
||||
if (isError)
|
||||
{
|
||||
@ -922,8 +919,8 @@ checkXactStatus(PGconn *conn, const char *cmdTag)
|
||||
|
||||
/*
|
||||
* Normally we get into INERROR state by detecting an Error message.
|
||||
* However, if we see one of these tags then we know for sure the
|
||||
* server is in abort state ...
|
||||
* However, if we see one of these tags then we know for sure the server
|
||||
* is in abort state ...
|
||||
*/
|
||||
else if (strcmp(cmdTag, "*ABORT STATE*") == 0) /* pre-7.3 only */
|
||||
conn->xactStatus = PQTRANS_INERROR;
|
||||
@ -949,9 +946,9 @@ getNotify(PGconn *conn)
|
||||
return EOF;
|
||||
|
||||
/*
|
||||
* Store the relation name right after the PQnotify structure so it
|
||||
* can all be freed at once. We don't use NAMEDATALEN because we
|
||||
* don't want to tie this interface to a specific server name length.
|
||||
* Store the relation name right after the PQnotify structure so it can
|
||||
* all be freed at once. We don't use NAMEDATALEN because we don't want
|
||||
* to tie this interface to a specific server name length.
|
||||
*/
|
||||
nmlen = strlen(conn->workBuffer.data);
|
||||
newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + 1);
|
||||
@ -1011,8 +1008,8 @@ pqGetCopyData2(PGconn *conn, char **buffer, int async)
|
||||
msgLength = conn->inCursor - conn->inStart;
|
||||
|
||||
/*
|
||||
* If it's the end-of-data marker, consume it, exit COPY_OUT mode,
|
||||
* and let caller read status with PQgetResult().
|
||||
* If it's the end-of-data marker, consume it, exit COPY_OUT mode, and
|
||||
* let caller read status with PQgetResult().
|
||||
*/
|
||||
if (msgLength == 3 &&
|
||||
strncmp(&conn->inBuffer[conn->inStart], "\\.\n", 3) == 0)
|
||||
@ -1069,8 +1066,8 @@ pqGetline2(PGconn *conn, char *s, int maxlen)
|
||||
}
|
||||
|
||||
/*
|
||||
* Since this is a purely synchronous routine, we don't bother to
|
||||
* maintain conn->inCursor; there is no need to back up.
|
||||
* Since this is a purely synchronous routine, we don't bother to maintain
|
||||
* conn->inCursor; there is no need to back up.
|
||||
*/
|
||||
while (maxlen > 1)
|
||||
{
|
||||
@ -1116,11 +1113,11 @@ pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize)
|
||||
return -1; /* we are not doing a copy... */
|
||||
|
||||
/*
|
||||
* Move data from libpq's buffer to the caller's. We want to accept
|
||||
* data only in units of whole lines, not partial lines. This ensures
|
||||
* that we can recognize the terminator line "\\.\n". (Otherwise, if
|
||||
* it happened to cross a packet/buffer boundary, we might hand the
|
||||
* first one or two characters off to the caller, which we shouldn't.)
|
||||
* Move data from libpq's buffer to the caller's. We want to accept data
|
||||
* only in units of whole lines, not partial lines. This ensures that we
|
||||
* can recognize the terminator line "\\.\n". (Otherwise, if it happened
|
||||
* to cross a packet/buffer boundary, we might hand the first one or two
|
||||
* characters off to the caller, which we shouldn't.)
|
||||
*/
|
||||
|
||||
conn->inCursor = conn->inStart;
|
||||
@ -1146,12 +1143,11 @@ pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize)
|
||||
|
||||
/*
|
||||
* We don't have a complete line. We'd prefer to leave it in libpq's
|
||||
* buffer until the rest arrives, but there is a special case: what if
|
||||
* the line is longer than the buffer the caller is offering us? In
|
||||
* that case we'd better hand over a partial line, else we'd get into
|
||||
* an infinite loop. Do this in a way that ensures we can't
|
||||
* misrecognize a terminator line later: leave last 3 characters in
|
||||
* libpq buffer.
|
||||
* buffer until the rest arrives, but there is a special case: what if the
|
||||
* line is longer than the buffer the caller is offering us? In that case
|
||||
* we'd better hand over a partial line, else we'd get into an infinite
|
||||
* loop. Do this in a way that ensures we can't misrecognize a terminator
|
||||
* line later: leave last 3 characters in libpq buffer.
|
||||
*/
|
||||
if (avail == 0 && bufsize > 3)
|
||||
{
|
||||
@ -1180,8 +1176,8 @@ pqEndcopy2(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure no data is waiting to be sent, abort if we are
|
||||
* non-blocking and the flush fails
|
||||
* make sure no data is waiting to be sent, abort if we are non-blocking
|
||||
* and the flush fails
|
||||
*/
|
||||
if (pqFlush(conn) && pqIsnonblocking(conn))
|
||||
return (1);
|
||||
@ -1208,8 +1204,8 @@ pqEndcopy2(PGconn *conn)
|
||||
* Trouble. For backwards-compatibility reasons, we issue the error
|
||||
* message as if it were a notice (would be nice to get rid of this
|
||||
* silliness, but too many apps probably don't handle errors from
|
||||
* PQendcopy reasonably). Note that the app can still obtain the
|
||||
* error status from the PGconn object.
|
||||
* PQendcopy reasonably). Note that the app can still obtain the error
|
||||
* status from the PGconn object.
|
||||
*/
|
||||
if (conn->errorMessage.len > 0)
|
||||
{
|
||||
@ -1225,17 +1221,17 @@ pqEndcopy2(PGconn *conn)
|
||||
PQclear(result);
|
||||
|
||||
/*
|
||||
* The worst case is that we've lost sync with the backend entirely
|
||||
* due to application screwup of the copy in/out protocol. To recover,
|
||||
* reset the connection (talk about using a sledgehammer...)
|
||||
* The worst case is that we've lost sync with the backend entirely due to
|
||||
* application screwup of the copy in/out protocol. To recover, reset the
|
||||
* connection (talk about using a sledgehammer...)
|
||||
*/
|
||||
pqInternalNotice(&conn->noticeHooks,
|
||||
"lost synchronization with server, resetting connection");
|
||||
"lost synchronization with server, resetting connection");
|
||||
|
||||
/*
|
||||
* Users doing non-blocking connections need to handle the reset
|
||||
* themselves, they'll need to check the connection status if we
|
||||
* return an error.
|
||||
* themselves, they'll need to check the connection status if we return an
|
||||
* error.
|
||||
*/
|
||||
if (pqIsnonblocking(conn))
|
||||
PQresetStart(conn);
|
||||
@ -1317,8 +1313,7 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the message. If we run out of data, loop around to try
|
||||
* again.
|
||||
* Scan the message. If we run out of data, loop around to try again.
|
||||
*/
|
||||
conn->inCursor = conn->inStart;
|
||||
needInput = true;
|
||||
@ -1328,8 +1323,8 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
|
||||
|
||||
/*
|
||||
* We should see V or E response to the command, but might get N
|
||||
* and/or A notices first. We also need to swallow the final Z
|
||||
* before returning.
|
||||
* and/or A notices first. We also need to swallow the final Z before
|
||||
* returning.
|
||||
*/
|
||||
switch (id)
|
||||
{
|
||||
@ -1365,7 +1360,7 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
|
||||
{
|
||||
/* The backend violates the protocol. */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("protocol error: id=0x%x\n"),
|
||||
libpq_gettext("protocol error: id=0x%x\n"),
|
||||
id);
|
||||
pqSaveErrorResult(conn);
|
||||
conn->inStart = conn->inCursor;
|
||||
@ -1397,7 +1392,7 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
|
||||
default:
|
||||
/* The backend violates the protocol. */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("protocol error: id=0x%x\n"),
|
||||
libpq_gettext("protocol error: id=0x%x\n"),
|
||||
id);
|
||||
pqSaveErrorResult(conn);
|
||||
conn->inStart = conn->inCursor;
|
||||
@ -1425,7 +1420,7 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
|
||||
*/
|
||||
char *
|
||||
pqBuildStartupPacket2(PGconn *conn, int *packetlen,
|
||||
const PQEnvironmentOption *options)
|
||||
const PQEnvironmentOption * options)
|
||||
{
|
||||
StartupPacket *startpacket;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.21 2005/06/12 00:00:21 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.22 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -51,8 +51,8 @@ static int getParameterStatus(PGconn *conn);
|
||||
static int getNotify(PGconn *conn);
|
||||
static int getCopyStart(PGconn *conn, ExecStatusType copytype);
|
||||
static int getReadyForQuery(PGconn *conn);
|
||||
static int build_startup_packet(const PGconn *conn, char *packet,
|
||||
const PQEnvironmentOption *options);
|
||||
static int build_startup_packet(const PGconn *conn, char *packet,
|
||||
const PQEnvironmentOption * options);
|
||||
|
||||
|
||||
/*
|
||||
@ -73,8 +73,8 @@ pqParseInput3(PGconn *conn)
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Try to read a message. First get the type code and length.
|
||||
* Return if not enough data.
|
||||
* Try to read a message. First get the type code and length. Return
|
||||
* if not enough data.
|
||||
*/
|
||||
conn->inCursor = conn->inStart;
|
||||
if (pqGetc(&id, conn))
|
||||
@ -83,9 +83,9 @@ pqParseInput3(PGconn *conn)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Try to validate message type/length here. A length less than 4
|
||||
* is definitely broken. Large lengths should only be believed
|
||||
* for a few message types.
|
||||
* Try to validate message type/length here. A length less than 4 is
|
||||
* definitely broken. Large lengths should only be believed for a few
|
||||
* message types.
|
||||
*/
|
||||
if (msgLength < 4)
|
||||
{
|
||||
@ -106,20 +106,20 @@ pqParseInput3(PGconn *conn)
|
||||
if (avail < msgLength)
|
||||
{
|
||||
/*
|
||||
* Before returning, enlarge the input buffer if needed to
|
||||
* hold the whole message. This is better than leaving it to
|
||||
* pqReadData because we can avoid multiple cycles of
|
||||
* realloc() when the message is large; also, we can implement
|
||||
* a reasonable recovery strategy if we are unable to make the
|
||||
* buffer big enough.
|
||||
* Before returning, enlarge the input buffer if needed to hold
|
||||
* the whole message. This is better than leaving it to
|
||||
* pqReadData because we can avoid multiple cycles of realloc()
|
||||
* when the message is large; also, we can implement a reasonable
|
||||
* recovery strategy if we are unable to make the buffer big
|
||||
* enough.
|
||||
*/
|
||||
if (pqCheckInBufferSpace(conn->inCursor + msgLength, conn))
|
||||
{
|
||||
/*
|
||||
* XXX add some better recovery code... plan is to skip
|
||||
* over the message using its length, then report an
|
||||
* error. For the moment, just treat this like loss of
|
||||
* sync (which indeed it might be!)
|
||||
* XXX add some better recovery code... plan is to skip over
|
||||
* the message using its length, then report an error. For the
|
||||
* moment, just treat this like loss of sync (which indeed it
|
||||
* might be!)
|
||||
*/
|
||||
handleSyncLoss(conn, id, msgLength);
|
||||
}
|
||||
@ -127,20 +127,20 @@ pqParseInput3(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTIFY and NOTICE messages can happen in any state; always
|
||||
* process them right away.
|
||||
* NOTIFY and NOTICE messages can happen in any state; always process
|
||||
* them right away.
|
||||
*
|
||||
* Most other messages should only be processed while in BUSY state.
|
||||
* (In particular, in READY state we hold off further parsing
|
||||
* until the application collects the current PGresult.)
|
||||
* Most other messages should only be processed while in BUSY state. (In
|
||||
* particular, in READY state we hold off further parsing until the
|
||||
* application collects the current PGresult.)
|
||||
*
|
||||
* However, if the state is IDLE then we got trouble; we need to deal
|
||||
* with the unexpected message somehow.
|
||||
*
|
||||
* ParameterStatus ('S') messages are a special case: in IDLE state
|
||||
* we must process 'em (this case could happen if a new value was
|
||||
* adopted from config file due to SIGHUP), but otherwise we hold
|
||||
* off until BUSY state.
|
||||
* ParameterStatus ('S') messages are a special case: in IDLE state we
|
||||
* must process 'em (this case could happen if a new value was adopted
|
||||
* from config file due to SIGHUP), but otherwise we hold off until
|
||||
* BUSY state.
|
||||
*/
|
||||
if (id == 'A')
|
||||
{
|
||||
@ -163,9 +163,9 @@ pqParseInput3(PGconn *conn)
|
||||
* ERROR messages are displayed using the notice processor;
|
||||
* ParameterStatus is handled normally; anything else is just
|
||||
* dropped on the floor after displaying a suitable warning
|
||||
* notice. (An ERROR is very possibly the backend telling us
|
||||
* why it is about to close the connection, so we don't want
|
||||
* to just discard it...)
|
||||
* notice. (An ERROR is very possibly the backend telling us why
|
||||
* it is about to close the connection, so we don't want to just
|
||||
* discard it...)
|
||||
*/
|
||||
if (id == 'E')
|
||||
{
|
||||
@ -180,7 +180,7 @@ pqParseInput3(PGconn *conn)
|
||||
else
|
||||
{
|
||||
pqInternalNotice(&conn->noticeHooks,
|
||||
"message type 0x%02x arrived from server while idle",
|
||||
"message type 0x%02x arrived from server while idle",
|
||||
id);
|
||||
/* Discard the unexpected message */
|
||||
conn->inCursor += msgLength;
|
||||
@ -199,7 +199,7 @@ pqParseInput3(PGconn *conn)
|
||||
if (conn->result == NULL)
|
||||
{
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_COMMAND_OK);
|
||||
PGRES_COMMAND_OK);
|
||||
if (!conn->result)
|
||||
return;
|
||||
}
|
||||
@ -221,7 +221,7 @@ pqParseInput3(PGconn *conn)
|
||||
if (conn->result == NULL)
|
||||
{
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_EMPTY_QUERY);
|
||||
PGRES_EMPTY_QUERY);
|
||||
if (!conn->result)
|
||||
return;
|
||||
}
|
||||
@ -234,7 +234,7 @@ pqParseInput3(PGconn *conn)
|
||||
if (conn->result == NULL)
|
||||
{
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_COMMAND_OK);
|
||||
PGRES_COMMAND_OK);
|
||||
if (!conn->result)
|
||||
return;
|
||||
}
|
||||
@ -252,9 +252,9 @@ pqParseInput3(PGconn *conn)
|
||||
case 'K': /* secret key data from the backend */
|
||||
|
||||
/*
|
||||
* This is expected only during backend startup, but
|
||||
* it's just as easy to handle it as part of the main
|
||||
* loop. Save the data and continue processing.
|
||||
* This is expected only during backend startup, but it's
|
||||
* just as easy to handle it as part of the main loop.
|
||||
* Save the data and continue processing.
|
||||
*/
|
||||
if (pqGetInt(&(conn->be_pid), 4, conn))
|
||||
return;
|
||||
@ -272,10 +272,10 @@ pqParseInput3(PGconn *conn)
|
||||
{
|
||||
/*
|
||||
* A new 'T' message is treated as the start of
|
||||
* another PGresult. (It is not clear that this
|
||||
* is really possible with the current backend.)
|
||||
* We stop parsing until the application accepts
|
||||
* the current result.
|
||||
* another PGresult. (It is not clear that this is
|
||||
* really possible with the current backend.) We stop
|
||||
* parsing until the application accepts the current
|
||||
* result.
|
||||
*/
|
||||
conn->asyncStatus = PGASYNC_READY;
|
||||
return;
|
||||
@ -285,13 +285,13 @@ pqParseInput3(PGconn *conn)
|
||||
|
||||
/*
|
||||
* NoData indicates that we will not be seeing a
|
||||
* RowDescription message because the statement or
|
||||
* portal inquired about doesn't return rows. Set up a
|
||||
* COMMAND_OK result, instead of TUPLES_OK.
|
||||
* RowDescription message because the statement or portal
|
||||
* inquired about doesn't return rows. Set up a COMMAND_OK
|
||||
* result, instead of TUPLES_OK.
|
||||
*/
|
||||
if (conn->result == NULL)
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_COMMAND_OK);
|
||||
PGRES_COMMAND_OK);
|
||||
break;
|
||||
case 'D': /* Data Row */
|
||||
if (conn->result != NULL &&
|
||||
@ -302,12 +302,11 @@ pqParseInput3(PGconn *conn)
|
||||
return;
|
||||
}
|
||||
else if (conn->result != NULL &&
|
||||
conn->result->resultStatus == PGRES_FATAL_ERROR)
|
||||
conn->result->resultStatus == PGRES_FATAL_ERROR)
|
||||
{
|
||||
/*
|
||||
* We've already choked for some reason. Just
|
||||
* discard tuples till we get to the end of the
|
||||
* query.
|
||||
* We've already choked for some reason. Just discard
|
||||
* tuples till we get to the end of the query.
|
||||
*/
|
||||
conn->inCursor += msgLength;
|
||||
}
|
||||
@ -335,19 +334,19 @@ pqParseInput3(PGconn *conn)
|
||||
case 'd': /* Copy Data */
|
||||
|
||||
/*
|
||||
* If we see Copy Data, just silently drop it. This
|
||||
* would only occur if application exits COPY OUT mode
|
||||
* too early.
|
||||
* If we see Copy Data, just silently drop it. This would
|
||||
* only occur if application exits COPY OUT mode too
|
||||
* early.
|
||||
*/
|
||||
conn->inCursor += msgLength;
|
||||
break;
|
||||
case 'c': /* Copy Done */
|
||||
|
||||
/*
|
||||
* If we see Copy Done, just silently drop it. This
|
||||
* is the normal case during PQendcopy. We will keep
|
||||
* swallowing data, expecting to see command-complete
|
||||
* for the COPY command.
|
||||
* If we see Copy Done, just silently drop it. This is
|
||||
* the normal case during PQendcopy. We will keep
|
||||
* swallowing data, expecting to see command-complete for
|
||||
* the COPY command.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
@ -395,7 +394,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"lost synchronization with server: got message type \"%c\", length %d\n"),
|
||||
"lost synchronization with server: got message type \"%c\", length %d\n"),
|
||||
id, msgLength);
|
||||
/* build an error result holding the error message */
|
||||
pqSaveErrorResult(conn);
|
||||
@ -618,16 +617,16 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
|
||||
|
||||
/*
|
||||
* Since the fields might be pretty long, we create a temporary
|
||||
* PQExpBuffer rather than using conn->workBuffer. workBuffer is
|
||||
* intended for stuff that is expected to be short. We shouldn't use
|
||||
* PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
|
||||
* for stuff that is expected to be short. We shouldn't use
|
||||
* conn->errorMessage either, since this might be only a notice.
|
||||
*/
|
||||
initPQExpBuffer(&workBuf);
|
||||
|
||||
/*
|
||||
* Make a PGresult to hold the accumulated fields. We temporarily lie
|
||||
* about the result status, so that PQmakeEmptyPGresult doesn't
|
||||
* uselessly copy conn->errorMessage.
|
||||
* about the result status, so that PQmakeEmptyPGresult doesn't uselessly
|
||||
* copy conn->errorMessage.
|
||||
*/
|
||||
res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
|
||||
if (!res)
|
||||
@ -808,9 +807,9 @@ getNotify(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the strings right after the PQnotify structure so it can all
|
||||
* be freed at once. We don't use NAMEDATALEN because we don't want
|
||||
* to tie this interface to a specific server name length.
|
||||
* Store the strings right after the PQnotify structure so it can all be
|
||||
* freed at once. We don't use NAMEDATALEN because we don't want to tie
|
||||
* this interface to a specific server name length.
|
||||
*/
|
||||
nmlen = strlen(svname);
|
||||
extralen = strlen(conn->workBuffer.data);
|
||||
@ -940,9 +939,9 @@ pqGetCopyData3(PGconn *conn, char **buffer, int async)
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Do we have the next input message? To make life simpler for
|
||||
* async callers, we keep returning 0 until the next message is
|
||||
* fully available, even if it is not Copy Data.
|
||||
* Do we have the next input message? To make life simpler for async
|
||||
* callers, we keep returning 0 until the next message is fully
|
||||
* available, even if it is not Copy Data.
|
||||
*/
|
||||
conn->inCursor = conn->inStart;
|
||||
if (pqGetc(&id, conn))
|
||||
@ -1017,7 +1016,7 @@ pqGetline3(PGconn *conn, char *s, int maxlen)
|
||||
conn->copy_is_binary)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("PQgetline: not doing text COPY OUT\n"));
|
||||
libpq_gettext("PQgetline: not doing text COPY OUT\n"));
|
||||
*s = '\0';
|
||||
return EOF;
|
||||
}
|
||||
@ -1070,9 +1069,8 @@ pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize)
|
||||
|
||||
/*
|
||||
* Recognize the next input message. To make life simpler for async
|
||||
* callers, we keep returning 0 until the next message is fully
|
||||
* available even if it is not Copy Data. This should keep PQendcopy
|
||||
* from blocking.
|
||||
* callers, we keep returning 0 until the next message is fully available
|
||||
* even if it is not Copy Data. This should keep PQendcopy from blocking.
|
||||
*/
|
||||
conn->inCursor = conn->inStart;
|
||||
if (pqGetc(&id, conn))
|
||||
@ -1084,8 +1082,8 @@ pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Cannot proceed unless it's a Copy Data message. Anything else
|
||||
* means end of copy mode.
|
||||
* Cannot proceed unless it's a Copy Data message. Anything else means
|
||||
* end of copy mode.
|
||||
*/
|
||||
if (id != 'd')
|
||||
return -1;
|
||||
@ -1144,8 +1142,8 @@ pqEndcopy3(PGconn *conn)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* If we sent the COPY command in extended-query mode, we must
|
||||
* issue a Sync as well.
|
||||
* If we sent the COPY command in extended-query mode, we must issue a
|
||||
* Sync as well.
|
||||
*/
|
||||
if (conn->queryclass != PGQUERY_SIMPLE)
|
||||
{
|
||||
@ -1156,8 +1154,8 @@ pqEndcopy3(PGconn *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure no data is waiting to be sent, abort if we are
|
||||
* non-blocking and the flush fails
|
||||
* make sure no data is waiting to be sent, abort if we are non-blocking
|
||||
* and the flush fails
|
||||
*/
|
||||
if (pqFlush(conn) && pqIsnonblocking(conn))
|
||||
return (1);
|
||||
@ -1167,12 +1165,11 @@ pqEndcopy3(PGconn *conn)
|
||||
resetPQExpBuffer(&conn->errorMessage);
|
||||
|
||||
/*
|
||||
* Non blocking connections may have to abort at this point. If
|
||||
* everyone played the game there should be no problem, but in error
|
||||
* scenarios the expected messages may not have arrived yet. (We are
|
||||
* assuming that the backend's packetizing will ensure that
|
||||
* CommandComplete arrives along with the CopyDone; are there corner
|
||||
* cases where that doesn't happen?)
|
||||
* Non blocking connections may have to abort at this point. If everyone
|
||||
* played the game there should be no problem, but in error scenarios the
|
||||
* expected messages may not have arrived yet. (We are assuming that the
|
||||
* backend's packetizing will ensure that CommandComplete arrives along
|
||||
* with the CopyDone; are there corner cases where that doesn't happen?)
|
||||
*/
|
||||
if (pqIsnonblocking(conn) && PQisBusy(conn))
|
||||
return (1);
|
||||
@ -1191,8 +1188,8 @@ pqEndcopy3(PGconn *conn)
|
||||
* Trouble. For backwards-compatibility reasons, we issue the error
|
||||
* message as if it were a notice (would be nice to get rid of this
|
||||
* silliness, but too many apps probably don't handle errors from
|
||||
* PQendcopy reasonably). Note that the app can still obtain the
|
||||
* error status from the PGconn object.
|
||||
* PQendcopy reasonably). Note that the app can still obtain the error
|
||||
* status from the PGconn object.
|
||||
*/
|
||||
if (conn->errorMessage.len > 0)
|
||||
{
|
||||
@ -1293,8 +1290,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the message. If we run out of data, loop around to try
|
||||
* again.
|
||||
* Scan the message. If we run out of data, loop around to try again.
|
||||
*/
|
||||
needInput = true;
|
||||
|
||||
@ -1305,9 +1301,9 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Try to validate message type/length here. A length less than 4
|
||||
* is definitely broken. Large lengths should only be believed
|
||||
* for a few message types.
|
||||
* Try to validate message type/length here. A length less than 4 is
|
||||
* definitely broken. Large lengths should only be believed for a few
|
||||
* message types.
|
||||
*/
|
||||
if (msgLength < 4)
|
||||
{
|
||||
@ -1328,16 +1324,16 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
if (avail < msgLength)
|
||||
{
|
||||
/*
|
||||
* Before looping, enlarge the input buffer if needed to hold
|
||||
* the whole message. See notes in parseInput.
|
||||
* Before looping, enlarge the input buffer if needed to hold the
|
||||
* whole message. See notes in parseInput.
|
||||
*/
|
||||
if (pqCheckInBufferSpace(conn->inCursor + msgLength, conn))
|
||||
{
|
||||
/*
|
||||
* XXX add some better recovery code... plan is to skip
|
||||
* over the message using its length, then report an
|
||||
* error. For the moment, just treat this like loss of
|
||||
* sync (which indeed it might be!)
|
||||
* XXX add some better recovery code... plan is to skip over
|
||||
* the message using its length, then report an error. For the
|
||||
* moment, just treat this like loss of sync (which indeed it
|
||||
* might be!)
|
||||
*/
|
||||
handleSyncLoss(conn, id, msgLength);
|
||||
break;
|
||||
@ -1347,8 +1343,8 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
|
||||
/*
|
||||
* We should see V or E response to the command, but might get N
|
||||
* and/or A notices first. We also need to swallow the final Z
|
||||
* before returning.
|
||||
* and/or A notices first. We also need to swallow the final Z before
|
||||
* returning.
|
||||
*/
|
||||
switch (id)
|
||||
{
|
||||
@ -1404,7 +1400,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
default:
|
||||
/* The backend violates the protocol. */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("protocol error: id=0x%x\n"),
|
||||
libpq_gettext("protocol error: id=0x%x\n"),
|
||||
id);
|
||||
pqSaveErrorResult(conn);
|
||||
/* trust the specified message length as what to skip */
|
||||
@ -1434,7 +1430,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
*/
|
||||
char *
|
||||
pqBuildStartupPacket3(PGconn *conn, int *packetlen,
|
||||
const PQEnvironmentOption *options)
|
||||
const PQEnvironmentOption * options)
|
||||
{
|
||||
char *startpacket;
|
||||
|
||||
@ -1457,7 +1453,7 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
|
||||
*/
|
||||
static int
|
||||
build_startup_packet(const PGconn *conn, char *packet,
|
||||
const PQEnvironmentOption *options)
|
||||
const PQEnvironmentOption * options)
|
||||
{
|
||||
int packet_len = 0;
|
||||
const PQEnvironmentOption *next_eo;
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.71 2005/08/28 16:37:48 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.72 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* [ Most of these notes are wrong/obsolete, but perhaps not all ]
|
||||
@ -274,15 +274,16 @@ pqsecure_open_client(PGconn *conn)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not establish SSL connection: %s\n"),
|
||||
libpq_gettext("could not establish SSL connection: %s\n"),
|
||||
err);
|
||||
SSLerrfree(err);
|
||||
close_SSL(conn);
|
||||
return PGRES_POLLING_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize errorMessage to empty. This allows open_client_SSL()
|
||||
* to detect whether client_cert_cb() has stored a message.
|
||||
* Initialize errorMessage to empty. This allows open_client_SSL() to
|
||||
* detect whether client_cert_cb() has stored a message.
|
||||
*/
|
||||
resetPQExpBuffer(&conn->errorMessage);
|
||||
}
|
||||
@ -332,11 +333,10 @@ rloop:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
|
||||
/*
|
||||
* Returning 0 here would cause caller to wait for
|
||||
* read-ready, which is not correct since what SSL wants
|
||||
* is wait for write-ready. The former could get us stuck
|
||||
* in an infinite wait, so don't risk it; busy-loop
|
||||
* instead.
|
||||
* Returning 0 here would cause caller to wait for read-ready,
|
||||
* which is not correct since what SSL wants is wait for
|
||||
* write-ready. The former could get us stuck in an infinite
|
||||
* wait, so don't risk it; busy-loop instead.
|
||||
*/
|
||||
goto rloop;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
@ -345,12 +345,12 @@ rloop:
|
||||
|
||||
if (n == -1)
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
else
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||
|
||||
SOCK_ERRNO_SET(ECONNRESET);
|
||||
n = -1;
|
||||
@ -362,7 +362,7 @@ rloop:
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL error: %s\n"), err);
|
||||
libpq_gettext("SSL error: %s\n"), err);
|
||||
SSLerrfree(err);
|
||||
}
|
||||
/* fall through */
|
||||
@ -372,7 +372,7 @@ rloop:
|
||||
break;
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("unrecognized SSL error code: %d\n"),
|
||||
libpq_gettext("unrecognized SSL error code: %d\n"),
|
||||
err);
|
||||
n = -1;
|
||||
break;
|
||||
@ -392,21 +392,21 @@ ssize_t
|
||||
pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
sigset_t osigmask;
|
||||
bool sigpipe_pending;
|
||||
bool got_epipe = false;
|
||||
|
||||
|
||||
|
||||
if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0)
|
||||
return -1;
|
||||
#else
|
||||
pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
{
|
||||
@ -422,8 +422,8 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
||||
|
||||
/*
|
||||
* Returning 0 here causes caller to wait for write-ready,
|
||||
* which is not really the right thing, but it's the best
|
||||
* we can do.
|
||||
* which is not really the right thing, but it's the best we
|
||||
* can do.
|
||||
*/
|
||||
n = 0;
|
||||
break;
|
||||
@ -441,13 +441,13 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
||||
got_epipe = true;
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
}
|
||||
else
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||
SOCK_ERRNO_SET(ECONNRESET);
|
||||
n = -1;
|
||||
}
|
||||
@ -458,7 +458,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL error: %s\n"), err);
|
||||
libpq_gettext("SSL error: %s\n"), err);
|
||||
SSLerrfree(err);
|
||||
}
|
||||
/* fall through */
|
||||
@ -468,7 +468,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
||||
break;
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("unrecognized SSL error code: %d\n"),
|
||||
libpq_gettext("unrecognized SSL error code: %d\n"),
|
||||
err);
|
||||
n = -1;
|
||||
break;
|
||||
@ -483,14 +483,14 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
||||
got_epipe = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe);
|
||||
#else
|
||||
pqsignal(SIGPIPE, oldsighandler);
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* WIN32 */
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -539,7 +539,7 @@ verify_peer(PGconn *conn)
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("error querying socket: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -553,10 +553,9 @@ verify_peer(PGconn *conn)
|
||||
int herrno = 0;
|
||||
|
||||
/*
|
||||
* Currently, pqGethostbyname() is used only on platforms that
|
||||
* don't have getaddrinfo(). If you enable this function, you
|
||||
* should convert the pqGethostbyname() function call to use
|
||||
* getaddrinfo().
|
||||
* Currently, pqGethostbyname() is used only on platforms that don't
|
||||
* have getaddrinfo(). If you enable this function, you should
|
||||
* convert the pqGethostbyname() function call to use getaddrinfo().
|
||||
*/
|
||||
pqGethostbyname(conn->peer_cn, &hpstr, buf, sizeof(buf),
|
||||
&h, &herrno);
|
||||
@ -566,7 +565,7 @@ verify_peer(PGconn *conn)
|
||||
if (h == NULL)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not get information about host \"%s\": %s\n"),
|
||||
libpq_gettext("could not get information about host \"%s\": %s\n"),
|
||||
conn->peer_cn, hstrerror(h_errno));
|
||||
return -1;
|
||||
}
|
||||
@ -608,19 +607,19 @@ verify_peer(PGconn *conn)
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
|
||||
conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
|
||||
conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
|
||||
(l >> 8) % 0x100, l % 0x100);
|
||||
break;
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext(
|
||||
"server common name \"%s\" does not resolve to peer address\n"),
|
||||
"server common name \"%s\" does not resolve to peer address\n"),
|
||||
conn->peer_cn);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif /* NOT_USED */
|
||||
#endif /* NOT_USED */
|
||||
|
||||
/*
|
||||
* Load precomputed DH parameters.
|
||||
@ -774,6 +773,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
{
|
||||
char homedir[MAXPGPATH];
|
||||
struct stat buf;
|
||||
|
||||
#ifndef WIN32
|
||||
struct stat buf2;
|
||||
#endif
|
||||
@ -786,7 +786,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not get user information\n"));
|
||||
libpq_gettext("could not get user information\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -795,7 +795,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
if ((fp = fopen(fnbuf, "r")) == NULL)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not open certificate file \"%s\": %s\n"),
|
||||
libpq_gettext("could not open certificate file \"%s\": %s\n"),
|
||||
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
return 0;
|
||||
}
|
||||
@ -804,7 +804,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not read certificate file \"%s\": %s\n"),
|
||||
libpq_gettext("could not read certificate file \"%s\": %s\n"),
|
||||
fnbuf, err);
|
||||
SSLerrfree(err);
|
||||
fclose(fp);
|
||||
@ -817,7 +817,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
if (stat(fnbuf, &buf) == -1)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("certificate present, but not private key file \"%s\"\n"),
|
||||
libpq_gettext("certificate present, but not private key file \"%s\"\n"),
|
||||
fnbuf);
|
||||
return 0;
|
||||
}
|
||||
@ -826,7 +826,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
buf.st_uid != geteuid())
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("private key file \"%s\" has wrong permissions\n"),
|
||||
libpq_gettext("private key file \"%s\" has wrong permissions\n"),
|
||||
fnbuf);
|
||||
return 0;
|
||||
}
|
||||
@ -834,7 +834,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
if ((fp = fopen(fnbuf, "r")) == NULL)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not open private key file \"%s\": %s\n"),
|
||||
libpq_gettext("could not open private key file \"%s\": %s\n"),
|
||||
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||
return 0;
|
||||
}
|
||||
@ -852,7 +852,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not read private key file \"%s\": %s\n"),
|
||||
libpq_gettext("could not read private key file \"%s\": %s\n"),
|
||||
fnbuf, err);
|
||||
SSLerrfree(err);
|
||||
fclose(fp);
|
||||
@ -866,7 +866,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
|
||||
libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
|
||||
fnbuf, err);
|
||||
SSLerrfree(err);
|
||||
return 0;
|
||||
@ -881,9 +881,9 @@ static unsigned long
|
||||
pq_threadidcallback(void)
|
||||
{
|
||||
/*
|
||||
* This is not starndard-compliant. pthread_self() returns
|
||||
* pthread_t, and shouldn't be cast to unsigned long, but
|
||||
* CRYPTO_set_id_callback requires it, so we have to do it.
|
||||
* This is not starndard-compliant. pthread_self() returns pthread_t, and
|
||||
* shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
|
||||
* it, so we have to do it.
|
||||
*/
|
||||
return (unsigned long) pthread_self();
|
||||
}
|
||||
@ -898,7 +898,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
|
||||
else
|
||||
pthread_mutex_unlock(&pq_lockarray[n]);
|
||||
}
|
||||
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
|
||||
static int
|
||||
@ -907,7 +906,6 @@ init_ssl_system(PGconn *conn)
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
#ifndef WIN32
|
||||
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#else
|
||||
static pthread_mutex_t init_mutex = NULL;
|
||||
static long mutex_initlock = 0;
|
||||
@ -954,7 +952,7 @@ init_ssl_system(PGconn *conn)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("could not create SSL context: %s\n"),
|
||||
libpq_gettext("could not create SSL context: %s\n"),
|
||||
err);
|
||||
SSLerrfree(err);
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
@ -1037,7 +1035,7 @@ open_client_SSL(PGconn *conn)
|
||||
r = SSL_connect(conn->ssl);
|
||||
if (r <= 0)
|
||||
{
|
||||
int err = SSL_get_error(conn->ssl, r);
|
||||
int err = SSL_get_error(conn->ssl, r);
|
||||
|
||||
switch (err)
|
||||
{
|
||||
@ -1053,11 +1051,11 @@ open_client_SSL(PGconn *conn)
|
||||
|
||||
if (r == -1)
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
else
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||
close_SSL(conn);
|
||||
return PGRES_POLLING_FAILED;
|
||||
}
|
||||
@ -1068,7 +1066,7 @@ open_client_SSL(PGconn *conn)
|
||||
* these will be detected by client_cert_cb() which is
|
||||
* called from SSL_connect(). We want to return that
|
||||
* error message and not the rather unhelpful error that
|
||||
* OpenSSL itself returns. So check to see if an error
|
||||
* OpenSSL itself returns. So check to see if an error
|
||||
* message was already stored.
|
||||
*/
|
||||
if (conn->errorMessage.len == 0)
|
||||
@ -1086,7 +1084,7 @@ open_client_SSL(PGconn *conn)
|
||||
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("unrecognized SSL error code: %d\n"),
|
||||
libpq_gettext("unrecognized SSL error code: %d\n"),
|
||||
err);
|
||||
close_SSL(conn);
|
||||
return PGRES_POLLING_FAILED;
|
||||
@ -1106,7 +1104,7 @@ open_client_SSL(PGconn *conn)
|
||||
if (r != X509_V_OK)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("certificate could not be validated: %s\n"),
|
||||
libpq_gettext("certificate could not be validated: %s\n"),
|
||||
X509_verify_cert_error_string(r));
|
||||
close_SSL(conn);
|
||||
return PGRES_POLLING_FAILED;
|
||||
@ -1120,7 +1118,7 @@ open_client_SSL(PGconn *conn)
|
||||
char *err = SSLerrmessage();
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("certificate could not be obtained: %s\n"),
|
||||
libpq_gettext("certificate could not be obtained: %s\n"),
|
||||
err);
|
||||
SSLerrfree(err);
|
||||
close_SSL(conn);
|
||||
@ -1142,8 +1140,8 @@ open_client_SSL(PGconn *conn)
|
||||
|
||||
/*
|
||||
* this is necessary to eliminate man-in-the-middle attacks and
|
||||
* impersonations where the attacker somehow learned the server's
|
||||
* private key
|
||||
* impersonations where the attacker somehow learned the server's private
|
||||
* key
|
||||
*/
|
||||
if (verify_peer(conn) == -1)
|
||||
{
|
||||
@ -1231,29 +1229,27 @@ PQgetssl(PGconn *conn)
|
||||
return NULL;
|
||||
return conn->ssl;
|
||||
}
|
||||
|
||||
#else /* !USE_SSL */
|
||||
#else /* !USE_SSL */
|
||||
|
||||
void *
|
||||
PQgetssl(PGconn *conn)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* USE_SSL */
|
||||
|
||||
#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
|
||||
|
||||
/*
|
||||
* Block SIGPIPE for this thread. This prevents send()/write() from exiting
|
||||
* Block SIGPIPE for this thread. This prevents send()/write() from exiting
|
||||
* the application.
|
||||
*/
|
||||
int
|
||||
pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
|
||||
{
|
||||
sigset_t sigpipe_sigset;
|
||||
sigset_t sigset;
|
||||
|
||||
sigset_t sigpipe_sigset;
|
||||
sigset_t sigset;
|
||||
|
||||
sigemptyset(&sigpipe_sigset);
|
||||
sigaddset(&sigpipe_sigset, SIGPIPE);
|
||||
|
||||
@ -1268,7 +1264,7 @@ pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
|
||||
/* Is there a pending SIGPIPE? */
|
||||
if (sigpending(&sigset) != 0)
|
||||
return -1;
|
||||
|
||||
|
||||
if (sigismember(&sigset, SIGPIPE))
|
||||
*sigpipe_pending = true;
|
||||
else
|
||||
@ -1276,15 +1272,15 @@ pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
|
||||
}
|
||||
else
|
||||
*sigpipe_pending = false;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Discard any pending SIGPIPE and reset the signal mask.
|
||||
*
|
||||
* Note: we are effectively assuming here that the C library doesn't queue
|
||||
* up multiple SIGPIPE events. If it did, then we'd accidentally leave
|
||||
* up multiple SIGPIPE events. If it did, then we'd accidentally leave
|
||||
* ours in the queue when an event was already pending and we got another.
|
||||
* As long as it doesn't queue multiple events, we're OK because the caller
|
||||
* can't tell the difference.
|
||||
@ -1295,15 +1291,15 @@ pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
|
||||
* gotten one, pass got_epipe = TRUE.
|
||||
*
|
||||
* We do not want this to change errno, since if it did that could lose
|
||||
* the error code from a preceding send(). We essentially assume that if
|
||||
* the error code from a preceding send(). We essentially assume that if
|
||||
* we were able to do pq_block_sigpipe(), this can't fail.
|
||||
*/
|
||||
void
|
||||
pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
|
||||
{
|
||||
int save_errno = SOCK_ERRNO;
|
||||
int signo;
|
||||
sigset_t sigset;
|
||||
int save_errno = SOCK_ERRNO;
|
||||
int signo;
|
||||
sigset_t sigset;
|
||||
|
||||
/* Clear SIGPIPE only if none was pending */
|
||||
if (got_epipe && !sigpipe_pending)
|
||||
@ -1311,19 +1307,19 @@ pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
|
||||
if (sigpending(&sigset) == 0 &&
|
||||
sigismember(&sigset, SIGPIPE))
|
||||
{
|
||||
sigset_t sigpipe_sigset;
|
||||
|
||||
sigset_t sigpipe_sigset;
|
||||
|
||||
sigemptyset(&sigpipe_sigset);
|
||||
sigaddset(&sigpipe_sigset, SIGPIPE);
|
||||
|
||||
sigwait(&sigpipe_sigset, &signo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Restore saved block mask */
|
||||
pthread_sigmask(SIG_SETMASK, osigset, NULL);
|
||||
|
||||
SOCK_ERRNO_SET(save_errno);
|
||||
}
|
||||
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.119 2005/09/24 17:53:28 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.120 2005/10/15 02:49:48 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -39,16 +39,16 @@ typedef enum
|
||||
{
|
||||
/*
|
||||
* Although it is okay to add to this list, values which become unused
|
||||
* should never be removed, nor should constants be redefined - that
|
||||
* would break compatibility with existing code.
|
||||
* should never be removed, nor should constants be redefined - that would
|
||||
* break compatibility with existing code.
|
||||
*/
|
||||
CONNECTION_OK,
|
||||
CONNECTION_BAD,
|
||||
/* Non-blocking mode only below here */
|
||||
|
||||
/*
|
||||
* The existence of these should never be relied upon - they should
|
||||
* only be used for user feedback or similar purposes.
|
||||
* The existence of these should never be relied upon - they should only
|
||||
* be used for user feedback or similar purposes.
|
||||
*/
|
||||
CONNECTION_STARTED, /* Waiting for connection to be made. */
|
||||
CONNECTION_MADE, /* Connection OK; waiting to send. */
|
||||
@ -78,12 +78,12 @@ typedef enum
|
||||
* anything was executed properly by the
|
||||
* backend */
|
||||
PGRES_TUPLES_OK, /* a query command that returns tuples was
|
||||
* executed properly by the backend,
|
||||
* PGresult contains the result tuples */
|
||||
* executed properly by the backend, PGresult
|
||||
* contains the result tuples */
|
||||
PGRES_COPY_OUT, /* Copy Out data transfer in progress */
|
||||
PGRES_COPY_IN, /* Copy In data transfer in progress */
|
||||
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from
|
||||
* the backend */
|
||||
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the
|
||||
* backend */
|
||||
PGRES_NONFATAL_ERROR, /* notice or warning message */
|
||||
PGRES_FATAL_ERROR /* query failed */
|
||||
} ExecStatusType;
|
||||
@ -146,8 +146,7 @@ typedef char pqbool;
|
||||
|
||||
typedef struct _PQprintOpt
|
||||
{
|
||||
pqbool header; /* print output field headings and row
|
||||
* count */
|
||||
pqbool header; /* print output field headings and row count */
|
||||
pqbool align; /* fill align the fields */
|
||||
pqbool standard; /* old brain dead format */
|
||||
pqbool html3; /* output html tables */
|
||||
@ -156,8 +155,8 @@ typedef struct _PQprintOpt
|
||||
char *fieldSep; /* field separator */
|
||||
char *tableOpt; /* insert to HTML <table ...> */
|
||||
char *caption; /* HTML <caption> */
|
||||
char **fieldName; /* null terminated array of replacement
|
||||
* field names */
|
||||
char **fieldName; /* null terminated array of replacement field
|
||||
* names */
|
||||
} PQprintOpt;
|
||||
|
||||
/* ----------------
|
||||
@ -175,11 +174,11 @@ typedef struct _PQconninfoOption
|
||||
char *compiled; /* Fallback compiled in default value */
|
||||
char *val; /* Option's current value, or NULL */
|
||||
char *label; /* Label for field in connect dialog */
|
||||
char *dispchar; /* Character to display for this field in
|
||||
* a connect dialog. Values are: ""
|
||||
* Display entered value as is "*"
|
||||
* Password field - hide value "D" Debug
|
||||
* option - don't show by default */
|
||||
char *dispchar; /* Character to display for this field in a
|
||||
* connect dialog. Values are: "" Display
|
||||
* entered value as is "*" Password field -
|
||||
* hide value "D" Debug option - don't show
|
||||
* by default */
|
||||
int dispsize; /* Field size in characters for dialog */
|
||||
} PQconninfoOption;
|
||||
|
||||
@ -321,8 +320,8 @@ extern PGresult *PQexecParams(PGconn *conn,
|
||||
const int *paramFormats,
|
||||
int resultFormat);
|
||||
extern PGresult *PQprepare(PGconn *conn, const char *stmtName,
|
||||
const char *query, int nParams,
|
||||
const Oid *paramTypes);
|
||||
const char *query, int nParams,
|
||||
const Oid *paramTypes);
|
||||
extern PGresult *PQexecPrepared(PGconn *conn,
|
||||
const char *stmtName,
|
||||
int nParams,
|
||||
@ -342,8 +341,8 @@ extern int PQsendQueryParams(PGconn *conn,
|
||||
const int *paramFormats,
|
||||
int resultFormat);
|
||||
extern int PQsendPrepare(PGconn *conn, const char *stmtName,
|
||||
const char *query, int nParams,
|
||||
const Oid *paramTypes);
|
||||
const char *query, int nParams,
|
||||
const Oid *paramTypes);
|
||||
extern int PQsendQueryPrepared(PGconn *conn,
|
||||
const char *stmtName,
|
||||
int nParams,
|
||||
@ -467,8 +466,7 @@ PQprintTuples(const PGresult *res,
|
||||
FILE *fout, /* output stream */
|
||||
int printAttName, /* print attribute names */
|
||||
int terseOutput, /* delimiter bars */
|
||||
int width); /* width of column, if 0, use variable
|
||||
* width */
|
||||
int width); /* width of column, if 0, use variable width */
|
||||
|
||||
|
||||
/* === in fe-lobj.c === */
|
||||
|
@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.107 2005/08/23 21:02:03 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.108 2005/10/15 02:49:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -39,8 +39,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef WIN32_CLIENT_ONLY
|
||||
typedef int ssize_t; /* ssize_t doesn't exist in VC (at least
|
||||
* not VC6) */
|
||||
typedef int ssize_t; /* ssize_t doesn't exist in VC (at least not
|
||||
* VC6) */
|
||||
#endif
|
||||
|
||||
/* include stuff common to fe and be */
|
||||
@ -92,7 +92,7 @@ typedef struct pgresAttDesc
|
||||
Oid typid; /* type id */
|
||||
int typlen; /* type size */
|
||||
int atttypmod; /* type-specific modifier info */
|
||||
} PGresAttDesc;
|
||||
} PGresAttDesc;
|
||||
|
||||
/*
|
||||
* Data for a single attribute of a single tuple
|
||||
@ -117,9 +117,8 @@ typedef struct pgresAttDesc
|
||||
typedef struct pgresAttValue
|
||||
{
|
||||
int len; /* length in bytes of the value */
|
||||
char *value; /* actual value, plus terminating zero
|
||||
* byte */
|
||||
} PGresAttValue;
|
||||
char *value; /* actual value, plus terminating zero byte */
|
||||
} PGresAttValue;
|
||||
|
||||
/* Typedef for message-field list entries */
|
||||
typedef struct pgMessageField
|
||||
@ -127,7 +126,7 @@ typedef struct pgMessageField
|
||||
struct pgMessageField *next; /* list link */
|
||||
char code; /* field code */
|
||||
char contents[1]; /* field value (VARIABLE LENGTH) */
|
||||
} PGMessageField;
|
||||
} PGMessageField;
|
||||
|
||||
/* Fields needed for notice handling */
|
||||
typedef struct
|
||||
@ -136,7 +135,7 @@ typedef struct
|
||||
void *noticeRecArg;
|
||||
PQnoticeProcessor noticeProc; /* notice message processor */
|
||||
void *noticeProcArg;
|
||||
} PGNoticeHooks;
|
||||
} PGNoticeHooks;
|
||||
|
||||
struct pg_result
|
||||
{
|
||||
@ -147,22 +146,21 @@ struct pg_result
|
||||
* PGresAttValue's */
|
||||
int tupArrSize; /* allocated size of tuples array */
|
||||
ExecStatusType resultStatus;
|
||||
char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the
|
||||
* query */
|
||||
char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */
|
||||
int binary; /* binary tuple values if binary == 1,
|
||||
* otherwise text */
|
||||
|
||||
/*
|
||||
* These fields are copied from the originating PGconn, so that
|
||||
* operations on the PGresult don't have to reference the PGconn.
|
||||
* These fields are copied from the originating PGconn, so that operations
|
||||
* on the PGresult don't have to reference the PGconn.
|
||||
*/
|
||||
PGNoticeHooks noticeHooks;
|
||||
int client_encoding; /* encoding id */
|
||||
|
||||
/*
|
||||
* Error information (all NULL if not an error result). errMsg is the
|
||||
* "overall" error message returned by PQresultErrorMessage. If we
|
||||
* have per-field info then it is stored in a linked list.
|
||||
* "overall" error message returned by PQresultErrorMessage. If we have
|
||||
* per-field info then it is stored in a linked list.
|
||||
*/
|
||||
char *errMsg; /* error message, or NULL if no error */
|
||||
PGMessageField *errFields; /* message broken into fields */
|
||||
@ -171,8 +169,8 @@ struct pg_result
|
||||
char null_field[1];
|
||||
|
||||
/*
|
||||
* Space management information. Note that attDescs and error stuff,
|
||||
* if not null, point into allocated blocks. But tuples points to a
|
||||
* Space management information. Note that attDescs and error stuff, if
|
||||
* not null, point into allocated blocks. But tuples points to a
|
||||
* separately malloc'd block, so that we can realloc it.
|
||||
*/
|
||||
PGresult_data *curBlock; /* most recently allocated block */
|
||||
@ -188,7 +186,7 @@ typedef enum
|
||||
PGASYNC_READY, /* result ready for PQgetResult */
|
||||
PGASYNC_COPY_IN, /* Copy In data transfer in progress */
|
||||
PGASYNC_COPY_OUT /* Copy Out data transfer in progress */
|
||||
} PGAsyncStatusType;
|
||||
} PGAsyncStatusType;
|
||||
|
||||
/* PGQueryClass tracks which query protocol we are now executing */
|
||||
typedef enum
|
||||
@ -196,7 +194,7 @@ typedef enum
|
||||
PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
|
||||
PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
|
||||
PGQUERY_PREPARE /* Parse only (PQprepare) */
|
||||
} PGQueryClass;
|
||||
} PGQueryClass;
|
||||
|
||||
/* PGSetenvStatusType defines the state of the PQSetenv state machine */
|
||||
/* (this is used only for 2.0-protocol connections) */
|
||||
@ -209,14 +207,14 @@ typedef enum
|
||||
SETENV_STATE_QUERY2_SEND, /* About to send a status query */
|
||||
SETENV_STATE_QUERY2_WAIT, /* Waiting for query to complete */
|
||||
SETENV_STATE_IDLE
|
||||
} PGSetenvStatusType;
|
||||
} PGSetenvStatusType;
|
||||
|
||||
/* Typedef for the EnvironmentOptions[] array */
|
||||
typedef struct PQEnvironmentOption
|
||||
{
|
||||
const char *envName, /* name of an environment variable */
|
||||
*pgName; /* name of corresponding SET variable */
|
||||
} PQEnvironmentOption;
|
||||
} PQEnvironmentOption;
|
||||
|
||||
/* Typedef for parameter-status list entries */
|
||||
typedef struct pgParameterStatus
|
||||
@ -225,7 +223,7 @@ typedef struct pgParameterStatus
|
||||
char *name; /* parameter name */
|
||||
char *value; /* parameter value */
|
||||
/* Note: name and value are stored in same malloc block as struct is */
|
||||
} pgParameterStatus;
|
||||
} pgParameterStatus;
|
||||
|
||||
/* large-object-access data ... allocated only if large-object code is used. */
|
||||
typedef struct pgLobjfuncs
|
||||
@ -239,7 +237,7 @@ typedef struct pgLobjfuncs
|
||||
Oid fn_lo_tell; /* OID of backend function lo_tell */
|
||||
Oid fn_lo_read; /* OID of backend function LOread */
|
||||
Oid fn_lo_write; /* OID of backend function LOwrite */
|
||||
} PGlobjfuncs;
|
||||
} PGlobjfuncs;
|
||||
|
||||
/*
|
||||
* PGconn stores all the state data associated with a single connection
|
||||
@ -248,16 +246,15 @@ typedef struct pgLobjfuncs
|
||||
struct pg_conn
|
||||
{
|
||||
/* Saved values of connection options */
|
||||
char *pghost; /* the machine on which the server is
|
||||
* running */
|
||||
char *pghostaddr; /* the IPv4 address of the machine on
|
||||
* which the server is running, in IPv4
|
||||
* numbers-and-dots notation. Takes
|
||||
* precedence over above. */
|
||||
char *pghost; /* the machine on which the server is running */
|
||||
char *pghostaddr; /* the IPv4 address of the machine on which
|
||||
* the server is running, in IPv4
|
||||
* numbers-and-dots notation. Takes precedence
|
||||
* over above. */
|
||||
char *pgport; /* the server's communication port */
|
||||
char *pgunixsocket; /* the Unix-domain socket that the server
|
||||
* is listening on; if NULL, uses a
|
||||
* default constructed from pgport */
|
||||
char *pgunixsocket; /* the Unix-domain socket that the server is
|
||||
* listening on; if NULL, uses a default
|
||||
* constructed from pgport */
|
||||
char *pgtty; /* tty on which the backend messages is
|
||||
* displayed (OBSOLETE, NOT USED) */
|
||||
char *connect_timeout; /* connection timeout (numeric string) */
|
||||
@ -267,7 +264,7 @@ struct pg_conn
|
||||
char *pgpass;
|
||||
char *sslmode; /* SSL mode (require,prefer,allow,disable) */
|
||||
#ifdef KRB5
|
||||
char *krbsrvname; /* Kerberos service name */
|
||||
char *krbsrvname; /* Kerberos service name */
|
||||
#endif
|
||||
|
||||
/* Optional file to write trace info to */
|
||||
@ -282,11 +279,11 @@ struct pg_conn
|
||||
PGTransactionStatusType xactStatus;
|
||||
/* note: xactStatus never changes to ACTIVE */
|
||||
PGQueryClass queryclass;
|
||||
bool nonblocking; /* whether this connection is using
|
||||
* nonblock sending semantics */
|
||||
bool nonblocking; /* whether this connection is using nonblock
|
||||
* sending semantics */
|
||||
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
|
||||
int copy_already_done; /* # bytes already returned in
|
||||
* COPY OUT */
|
||||
int copy_already_done; /* # bytes already returned in COPY
|
||||
* OUT */
|
||||
PGnotify *notifyHead; /* oldest unreported Notify msg */
|
||||
PGnotify *notifyTail; /* newest unreported Notify msg */
|
||||
|
||||
@ -312,17 +309,14 @@ struct pg_conn
|
||||
pgParameterStatus *pstatus; /* ParameterStatus data */
|
||||
int client_encoding; /* encoding id */
|
||||
PGVerbosity verbosity; /* error/notice message verbosity */
|
||||
PGlobjfuncs *lobjfuncs; /* private state for large-object access
|
||||
* fns */
|
||||
PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */
|
||||
|
||||
/* Buffer for data received from backend and not yet processed */
|
||||
char *inBuffer; /* currently allocated buffer */
|
||||
int inBufSize; /* allocated size of buffer */
|
||||
int inStart; /* offset to first unconsumed data in
|
||||
* buffer */
|
||||
int inStart; /* offset to first unconsumed data in buffer */
|
||||
int inCursor; /* next byte to tentatively consume */
|
||||
int inEnd; /* offset to first position after avail
|
||||
* data */
|
||||
int inEnd; /* offset to first position after avail data */
|
||||
|
||||
/* Buffer for data not yet sent to backend */
|
||||
char *outBuffer; /* currently allocated buffer */
|
||||
@ -330,8 +324,8 @@ struct pg_conn
|
||||
int outCount; /* number of chars waiting in buffer */
|
||||
|
||||
/* State for constructing messages in outBuffer */
|
||||
int outMsgStart; /* offset to msg start (length word); if
|
||||
* -1, msg has no length word */
|
||||
int outMsgStart; /* offset to msg start (length word); if -1,
|
||||
* msg has no length word */
|
||||
int outMsgEnd; /* offset to msg end (so far) */
|
||||
|
||||
/* Status for asynchronous result construction */
|
||||
@ -408,10 +402,10 @@ extern void pqClearAsyncResult(PGconn *conn);
|
||||
extern void pqSaveErrorResult(PGconn *conn);
|
||||
extern PGresult *pqPrepareAsyncResult(PGconn *conn);
|
||||
extern void
|
||||
pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt, ...)
|
||||
pqInternalNotice(const PGNoticeHooks * hooks, const char *fmt,...)
|
||||
/* This lets gcc check the format string for consistency. */
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
extern int pqAddTuple(PGresult *res, PGresAttValue *tup);
|
||||
extern int pqAddTuple(PGresult *res, PGresAttValue * tup);
|
||||
extern void pqSaveMessageField(PGresult *res, char code,
|
||||
const char *value);
|
||||
extern void pqSaveParameterStatus(PGconn *conn, const char *name,
|
||||
@ -423,7 +417,7 @@ extern void pqHandleSendFailure(PGconn *conn);
|
||||
extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn);
|
||||
|
||||
extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen,
|
||||
const PQEnvironmentOption *options);
|
||||
const PQEnvironmentOption * options);
|
||||
extern void pqParseInput2(PGconn *conn);
|
||||
extern int pqGetCopyData2(PGconn *conn, char **buffer, int async);
|
||||
extern int pqGetline2(PGconn *conn, char *s, int maxlen);
|
||||
@ -437,7 +431,7 @@ extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid,
|
||||
/* === in fe-protocol3.c === */
|
||||
|
||||
extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen,
|
||||
const PQEnvironmentOption *options);
|
||||
const PQEnvironmentOption * options);
|
||||
extern void pqParseInput3(PGconn *conn);
|
||||
extern int pqGetErrorNotice3(PGconn *conn, bool isError);
|
||||
extern int pqGetCopyData3(PGconn *conn, char **buffer, int async);
|
||||
@ -452,8 +446,8 @@ extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid,
|
||||
/* === in fe-misc.c === */
|
||||
|
||||
/*
|
||||
* "Get" and "Put" routines return 0 if successful, EOF if not. Note that
|
||||
* for Get, EOF merely means the buffer is exhausted, not that there is
|
||||
* "Get" and "Put" routines return 0 if successful, EOF if not. Note that for
|
||||
* Get, EOF merely means the buffer is exhausted, not that there is
|
||||
* necessarily any error.
|
||||
*/
|
||||
extern int pqCheckOutBufferSpace(int bytes_needed, PGconn *conn);
|
||||
@ -488,7 +482,7 @@ extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
|
||||
#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
|
||||
extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
|
||||
extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
|
||||
bool got_epipe);
|
||||
bool got_epipe);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -501,7 +495,6 @@ extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
|
||||
extern char *
|
||||
libpq_gettext(const char *msgid)
|
||||
__attribute__((format_arg(1)));
|
||||
|
||||
#else
|
||||
#define libpq_gettext(x) (x)
|
||||
#endif
|
||||
|
@ -17,7 +17,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.20 2004/12/31 22:03:50 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.21 2005/10/15 02:49:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -135,9 +135,9 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
|
||||
char *newdata;
|
||||
|
||||
/*
|
||||
* Guard against ridiculous "needed" values, which can occur if we're
|
||||
* fed bogus data. Without this, we can get an overflow or infinite
|
||||
* loop in the following.
|
||||
* Guard against ridiculous "needed" values, which can occur if we're fed
|
||||
* bogus data. Without this, we can get an overflow or infinite loop in
|
||||
* the following.
|
||||
*/
|
||||
if (needed >= ((size_t) INT_MAX - str->len))
|
||||
return 0;
|
||||
@ -150,19 +150,18 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
|
||||
return 1; /* got enough space already */
|
||||
|
||||
/*
|
||||
* We don't want to allocate just a little more space with each
|
||||
* append; for efficiency, double the buffer size each time it
|
||||
* overflows. Actually, we might need to more than double it if
|
||||
* 'needed' is big...
|
||||
* We don't want to allocate just a little more space with each append;
|
||||
* for efficiency, double the buffer size each time it overflows.
|
||||
* Actually, we might need to more than double it if 'needed' is big...
|
||||
*/
|
||||
newlen = (str->maxlen > 0) ? (2 * str->maxlen) : 64;
|
||||
while (needed > newlen)
|
||||
newlen = 2 * newlen;
|
||||
|
||||
/*
|
||||
* Clamp to INT_MAX in case we went past it. Note we are assuming
|
||||
* here that INT_MAX <= UINT_MAX/2, else the above loop could
|
||||
* overflow. We will still have newlen >= needed.
|
||||
* Clamp to INT_MAX in case we went past it. Note we are assuming here
|
||||
* that INT_MAX <= UINT_MAX/2, else the above loop could overflow. We
|
||||
* will still have newlen >= needed.
|
||||
*/
|
||||
if (newlen > (size_t) INT_MAX)
|
||||
newlen = (size_t) INT_MAX;
|
||||
@ -197,8 +196,8 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
{
|
||||
/*
|
||||
* Try to format the given string into the available space; but if
|
||||
* there's hardly any space, don't bother trying, just fall
|
||||
* through to enlarge the buffer first.
|
||||
* there's hardly any space, don't bother trying, just fall through to
|
||||
* enlarge the buffer first.
|
||||
*/
|
||||
if (str->maxlen > str->len + 16)
|
||||
{
|
||||
@ -245,8 +244,8 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
{
|
||||
/*
|
||||
* Try to format the given string into the available space; but if
|
||||
* there's hardly any space, don't bother trying, just fall
|
||||
* through to enlarge the buffer first.
|
||||
* there's hardly any space, don't bother trying, just fall through to
|
||||
* enlarge the buffer first.
|
||||
*/
|
||||
if (str->maxlen > str->len + 16)
|
||||
{
|
||||
@ -321,8 +320,8 @@ appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
|
||||
str->len += datalen;
|
||||
|
||||
/*
|
||||
* Keep a trailing null in place, even though it's probably useless
|
||||
* for binary data...
|
||||
* Keep a trailing null in place, even though it's probably useless for
|
||||
* binary data...
|
||||
*/
|
||||
str->data[str->len] = '\0';
|
||||
}
|
||||
|
@ -5,13 +5,15 @@ typedef ULONG pthread_key_t;
|
||||
typedef HANDLE pthread_mutex_t;
|
||||
typedef int pthread_once_t;
|
||||
|
||||
DWORD pthread_self();
|
||||
DWORD pthread_self();
|
||||
|
||||
void pthread_setspecific(pthread_key_t, void*);
|
||||
void* pthread_getspecific(pthread_key_t);
|
||||
void pthread_setspecific(pthread_key_t, void *);
|
||||
void *pthread_getspecific(pthread_key_t);
|
||||
|
||||
void pthread_mutex_init(pthread_mutex_t *, void *attr);
|
||||
void pthread_mutex_lock(pthread_mutex_t*); // blocking
|
||||
void pthread_mutex_unlock(pthread_mutex_t*);
|
||||
void pthread_mutex_init(pthread_mutex_t *, void *attr);
|
||||
void pthread_mutex_lock(pthread_mutex_t *);
|
||||
|
||||
//blocking
|
||||
void pthread_mutex_unlock(pthread_mutex_t *);
|
||||
|
||||
#endif
|
||||
|
@ -290,7 +290,7 @@ winsock_strerror(int err, char *strerrbuf, size_t buflen)
|
||||
dlls[i].handle = (void *) LoadLibraryEx(
|
||||
dlls[i].dll_name,
|
||||
0,
|
||||
LOAD_LIBRARY_AS_DATAFILE);
|
||||
LOAD_LIBRARY_AS_DATAFILE);
|
||||
}
|
||||
|
||||
if (dlls[i].dll_name && !dlls[i].handle)
|
||||
@ -303,7 +303,7 @@ winsock_strerror(int err, char *strerrbuf, size_t buflen)
|
||||
success = 0 != FormatMessage(
|
||||
flags,
|
||||
dlls[i].handle, err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
strerrbuf, buflen - 64,
|
||||
0
|
||||
);
|
||||
|
Reference in New Issue
Block a user