@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $ Header : / cvsroot / pgsql / src / interfaces / libpq / fe - exec . c , v 1.80 1999 / 05 / 25 16 : 15 : 12 momjian Exp $
* $ Header : / cvsroot / pgsql / src / interfaces / libpq / fe - exec . c , v 1.81 1999 / 05 / 28 01 : 54 : 53 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -47,6 +47,7 @@ const char *const pgresStatus[] = {
static int addTuple ( PGresult * res , PGresAttValue * tup ) ;
static void parseInput ( PGconn * conn ) ;
static void handleSendFailure ( PGconn * conn ) ;
static int getRowDescriptions ( PGconn * conn ) ;
static int getAnotherTuple ( PGconn * conn , int binary ) ;
static int getNotify ( PGconn * conn ) ;
@ -433,18 +434,53 @@ PQsendQuery(PGconn *conn, const char *query)
/* send the query to the backend; */
/* the frontend-backend protocol uses 'Q' to designate queries */
if ( pqPutnchar ( " Q " , 1 , conn ) )
return 0 ;
if ( pqPuts ( query , conn ) )
return 0 ;
if ( pqFlush ( conn ) )
if ( pqPutnchar ( " Q " , 1 , conn ) | |
pqPuts ( query , conn ) | |
pqFlush ( conn ) )
{
handleSendFailure ( conn ) ;
return 0 ;
}
/* OK, it's launched! */
conn - > asyncStatus = PGASYNC_BUSY ;
return 1 ;
}
/*
* handleSendFailure : try to clean up after failure to send command .
*
* Primarily , what we want to accomplish here is to process an async
* NOTICE message that the backend might have sent just before it died .
*
* NOTE : this routine should only be called in PGASYNC_IDLE state .
*/
static void
handleSendFailure ( PGconn * conn )
{
/* Preserve the error message emitted by the failing output routine */
char * svErrMsg = strdup ( conn - > errorMessage ) ;
/*
* 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 .
*/
while ( pqReadData ( conn ) > 0 )
/* loop until no more data readable */ ;
/*
* Parse any available input messages . Since we are in PGASYNC_IDLE
* state , only NOTICE and NOTIFY messages will be eaten .
*/
parseInput ( conn ) ;
/* Restore error message generated by output routine, if any. */
if ( * svErrMsg ! = ' \0 ' )
strcpy ( conn - > errorMessage , svErrMsg ) ;
free ( svErrMsg ) ;
}
/*
* Consume any available input from the backend
@ -1399,31 +1435,44 @@ PQfn(PGconn *conn,
/* clear the error string */
conn - > errorMessage [ 0 ] = ' \0 ' ;
if ( pqPuts ( " F " , conn ) ) /* function */
return NULL ;
if ( pqPutInt ( fnid , 4 , conn ) ) /* function id */
return NULL ;
if ( pqPutInt ( nargs , 4 , conn ) ) /* # of args */
if ( pqPuts ( " F " , conn ) | | /* function */
pqPutInt ( fnid , 4 , conn ) | | /* function id */
pqPutInt ( nargs , 4 , conn ) ) /* # of args */
{
handleSendFailure ( conn ) ;
return NULL ;
}
for ( i = 0 ; i < nargs ; + + i )
{ /* len.int4 + contents */
if ( pqPutInt ( args [ i ] . len , 4 , conn ) )
{
handleSendFailure ( conn ) ;
return NULL ;
}
if ( args [ i ] . isint )
{
if ( pqPutInt ( args [ i ] . u . integer , 4 , conn ) )
{
handleSendFailure ( conn ) ;
return NULL ;
}
}
else
{
if ( pqPutnchar ( ( char * ) args [ i ] . u . ptr , args [ i ] . len , conn ) )
{
handleSendFailure ( conn ) ;
return NULL ;
}
}
}
if ( pqFlush ( conn ) )
{
handleSendFailure ( conn ) ;
return NULL ;
}
for ( ; ; )
{