@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / interfaces / libpq / fe - protocol3 . c , v 1.20 2004 / 12 / 31 22 : 03 : 50 pgsql Exp $
* $ PostgreSQL : pgsql / src / interfaces / libpq / fe - protocol3 . c , v 1.21 2005 / 06 / 12 00 : 00 : 21 neilc Exp $
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
@ -51,7 +51,7 @@ static int getParameterStatus(PGconn *conn);
static int getNotify ( PGconn * conn ) ;
static int getNotify ( PGconn * conn ) ;
static int getCopyStart ( PGconn * conn , ExecStatusType copytype ) ;
static int getCopyStart ( PGconn * conn , ExecStatusType copytype ) ;
static int getReadyForQuery ( PGconn * conn ) ;
static int getReadyForQuery ( PGconn * conn ) ;
static int build_startup_packet ( const PGconn * conn , char * packet ,
static int build_startup_packet ( const PGconn * conn , char * packet ,
const PQEnvironmentOption * options ) ;
const PQEnvironmentOption * options ) ;
@ -197,8 +197,12 @@ pqParseInput3(PGconn *conn)
if ( pqGets ( & conn - > workBuffer , conn ) )
if ( pqGets ( & conn - > workBuffer , conn ) )
return ;
return ;
if ( conn - > result = = NULL )
if ( conn - > result = = NULL )
{
conn - > result = PQmakeEmptyPGresult ( conn ,
conn - > result = PQmakeEmptyPGresult ( conn ,
PGRES_COMMAND_OK ) ;
PGRES_COMMAND_OK ) ;
if ( ! conn - > result )
return ;
}
strncpy ( conn - > result - > cmdStatus , conn - > workBuffer . data ,
strncpy ( conn - > result - > cmdStatus , conn - > workBuffer . data ,
CMDSTATUS_LEN ) ;
CMDSTATUS_LEN ) ;
conn - > asyncStatus = PGASYNC_READY ;
conn - > asyncStatus = PGASYNC_READY ;
@ -215,8 +219,12 @@ pqParseInput3(PGconn *conn)
break ;
break ;
case ' I ' : /* empty query */
case ' I ' : /* empty query */
if ( conn - > result = = NULL )
if ( conn - > result = = NULL )
{
conn - > result = PQmakeEmptyPGresult ( conn ,
conn - > result = PQmakeEmptyPGresult ( conn ,
PGRES_EMPTY_QUERY ) ;
PGRES_EMPTY_QUERY ) ;
if ( ! conn - > result )
return ;
}
conn - > asyncStatus = PGASYNC_READY ;
conn - > asyncStatus = PGASYNC_READY ;
break ;
break ;
case ' 1 ' : /* Parse Complete */
case ' 1 ' : /* Parse Complete */
@ -224,8 +232,12 @@ pqParseInput3(PGconn *conn)
if ( conn - > queryclass = = PGQUERY_PREPARE )
if ( conn - > queryclass = = PGQUERY_PREPARE )
{
{
if ( conn - > result = = NULL )
if ( conn - > result = = NULL )
{
conn - > result = PQmakeEmptyPGresult ( conn ,
conn - > result = PQmakeEmptyPGresult ( conn ,
PGRES_COMMAND_OK ) ;
PGRES_COMMAND_OK ) ;
if ( ! conn - > result )
return ;
}
conn - > asyncStatus = PGASYNC_READY ;
conn - > asyncStatus = PGASYNC_READY ;
}
}
break ;
break ;
@ -412,14 +424,13 @@ getRowDescriptions(PGconn *conn)
int i ;
int i ;
result = PQmakeEmptyPGresult ( conn , PGRES_TUPLES_OK ) ;
result = PQmakeEmptyPGresult ( conn , PGRES_TUPLES_OK ) ;
if ( ! result )
goto failure ;
/* parseInput already read the 'T' label and message length. */
/* parseInput already read the 'T' label and message length. */
/* the next two bytes are the number of fields */
/* the next two bytes are the number of fields */
if ( pqGetInt ( & ( result - > numAttributes ) , 2 , conn ) )
if ( pqGetInt ( & ( result - > numAttributes ) , 2 , conn ) )
{
goto failure ;
PQclear ( result ) ;
return EOF ;
}
nfields = result - > numAttributes ;
nfields = result - > numAttributes ;
/* allocate space for the attribute descriptors */
/* allocate space for the attribute descriptors */
@ -427,7 +438,9 @@ getRowDescriptions(PGconn *conn)
{
{
result - > attDescs = ( PGresAttDesc * )
result - > attDescs = ( PGresAttDesc * )
pqResultAlloc ( result , nfields * sizeof ( PGresAttDesc ) , TRUE ) ;
pqResultAlloc ( result , nfields * sizeof ( PGresAttDesc ) , TRUE ) ;
MemSet ( ( char * ) result - > attDescs , 0 , nfields * sizeof ( PGresAttDesc ) ) ;
if ( ! result - > attDescs )
goto failure ;
MemSet ( result - > attDescs , 0 , nfields * sizeof ( PGresAttDesc ) ) ;
}
}
/* result->binary is true only if ALL columns are binary */
/* result->binary is true only if ALL columns are binary */
@ -451,8 +464,7 @@ getRowDescriptions(PGconn *conn)
pqGetInt ( & atttypmod , 4 , conn ) | |
pqGetInt ( & atttypmod , 4 , conn ) | |
pqGetInt ( & format , 2 , conn ) )
pqGetInt ( & format , 2 , conn ) )
{
{
PQclear ( result ) ;
goto failure ;
return EOF ;
}
}
/*
/*
@ -465,6 +477,8 @@ getRowDescriptions(PGconn *conn)
result - > attDescs [ i ] . name = pqResultStrdup ( result ,
result - > attDescs [ i ] . name = pqResultStrdup ( result ,
conn - > workBuffer . data ) ;
conn - > workBuffer . data ) ;
if ( ! result - > attDescs [ i ] . name )
goto failure ;
result - > attDescs [ i ] . tableid = tableid ;
result - > attDescs [ i ] . tableid = tableid ;
result - > attDescs [ i ] . columnid = columnid ;
result - > attDescs [ i ] . columnid = columnid ;
result - > attDescs [ i ] . format = format ;
result - > attDescs [ i ] . format = format ;
@ -479,6 +493,10 @@ getRowDescriptions(PGconn *conn)
/* Success! */
/* Success! */
conn - > result = result ;
conn - > result = result ;
return 0 ;
return 0 ;
failure :
PQclear ( result ) ;
return EOF ;
}
}
/*
/*
@ -507,7 +525,7 @@ getAnotherTuple(PGconn *conn, int msgLength)
pqResultAlloc ( result , nfields * sizeof ( PGresAttValue ) , TRUE ) ;
pqResultAlloc ( result , nfields * sizeof ( PGresAttValue ) , TRUE ) ;
if ( conn - > curTuple = = NULL )
if ( conn - > curTuple = = NULL )
goto outOfMemory ;
goto outOfMemory ;
MemSet ( ( char * ) conn - > curTuple , 0 , nfields * sizeof ( PGresAttValue ) ) ;
MemSet ( conn - > curTuple , 0 , nfields * sizeof ( PGresAttValue ) ) ;
}
}
tup = conn - > curTuple ;
tup = conn - > curTuple ;
@ -593,19 +611,11 @@ outOfMemory:
int
int
pqGetErrorNotice3 ( PGconn * conn , bool isError )
pqGetErrorNotice3 ( PGconn * conn , bool isError )
{
{
PGresult * res ;
PGresult * res = NULL ;
PQExpBufferData workBuf ;
PQExpBufferData workBuf ;
char id ;
char id ;
const char * val ;
const char * val ;
/*
* Make a PGresult to hold the accumulated fields . We temporarily lie
* about the result status , so that PQmakeEmptyPGresult doesn ' t
* uselessly copy conn - > errorMessage .
*/
res = PQmakeEmptyPGresult ( conn , PGRES_EMPTY_QUERY ) ;
res - > resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR ;
/*
/*
* Since the fields might be pretty long , we create a temporary
* Since the fields might be pretty long , we create a temporary
* PQExpBuffer rather than using conn - > workBuffer . workBuffer is
* PQExpBuffer rather than using conn - > workBuffer . workBuffer is
@ -614,6 +624,16 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
*/
*/
initPQExpBuffer ( & workBuf ) ;
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 .
*/
res = PQmakeEmptyPGresult ( conn , PGRES_EMPTY_QUERY ) ;
if ( ! res )
goto fail ;
res - > resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR ;
/*
/*
* Read the fields and save into res .
* Read the fields and save into res .
*/
*/
@ -702,6 +722,8 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
if ( isError )
if ( isError )
{
{
res - > errMsg = pqResultStrdup ( res , workBuf . data ) ;
res - > errMsg = pqResultStrdup ( res , workBuf . data ) ;
if ( ! res - > errMsg )
goto fail ;
pqClearAsyncResult ( conn ) ;
pqClearAsyncResult ( conn ) ;
conn - > result = res ;
conn - > result = res ;
resetPQExpBuffer ( & conn - > errorMessage ) ;
resetPQExpBuffer ( & conn - > errorMessage ) ;
@ -825,19 +847,15 @@ getCopyStart(PGconn *conn, ExecStatusType copytype)
int i ;
int i ;
result = PQmakeEmptyPGresult ( conn , copytype ) ;
result = PQmakeEmptyPGresult ( conn , copytype ) ;
if ( ! result )
goto failure ;
if ( pqGetc ( & conn - > copy_is_binary , conn ) )
if ( pqGetc ( & conn - > copy_is_binary , conn ) )
{
goto failure ;
PQclear ( result ) ;
return EOF ;
}
result - > binary = conn - > copy_is_binary ;
result - > binary = conn - > copy_is_binary ;
/* the next two bytes are the number of fields */
/* the next two bytes are the number of fields */
if ( pqGetInt ( & ( result - > numAttributes ) , 2 , conn ) )
if ( pqGetInt ( & ( result - > numAttributes ) , 2 , conn ) )
{
goto failure ;
PQclear ( result ) ;
return EOF ;
}
nfields = result - > numAttributes ;
nfields = result - > numAttributes ;
/* allocate space for the attribute descriptors */
/* allocate space for the attribute descriptors */
@ -845,7 +863,9 @@ getCopyStart(PGconn *conn, ExecStatusType copytype)
{
{
result - > attDescs = ( PGresAttDesc * )
result - > attDescs = ( PGresAttDesc * )
pqResultAlloc ( result , nfields * sizeof ( PGresAttDesc ) , TRUE ) ;
pqResultAlloc ( result , nfields * sizeof ( PGresAttDesc ) , TRUE ) ;
MemSet ( ( char * ) result - > attDescs , 0 , nfields * sizeof ( PGresAttDesc ) ) ;
if ( ! result - > attDescs )
goto failure ;
MemSet ( result - > attDescs , 0 , nfields * sizeof ( PGresAttDesc ) ) ;
}
}
for ( i = 0 ; i < nfields ; i + + )
for ( i = 0 ; i < nfields ; i + + )
@ -853,23 +873,23 @@ getCopyStart(PGconn *conn, ExecStatusType copytype)
int format ;
int format ;
if ( pqGetInt ( & format , 2 , conn ) )
if ( pqGetInt ( & format , 2 , conn ) )
{
goto failure ;
PQclear ( result ) ;
return EOF ;
}
/*
/*
* Since pqGetInt treats 2 - byte integers as unsigned , we need to
* Since pqGetInt treats 2 - byte integers as unsigned , we need to
* coerce these results to signed form .
* coerce these results to signed form .
*/
*/
format = ( int ) ( ( int16 ) format ) ;
format = ( int ) ( ( int16 ) format ) ;
result - > attDescs [ i ] . format = format ;
result - > attDescs [ i ] . format = format ;
}
}
/* Success! */
/* Success! */
conn - > result = result ;
conn - > result = result ;
return 0 ;
return 0 ;
failure :
PQclear ( result ) ;
return EOF ;
}
}
/*
/*