@ -8,7 +8,7 @@
* Darko Prenosil < Darko . Prenosil @ finteh . hr >
* Shridhar Daithankar < shridhar_daithankar @ persistent . co . in >
*
* $ PostgreSQL : pgsql / contrib / dblink / dblink . c , v 1.73 2008 / 04 / 04 17 : 02 : 56 momjian Exp $
* $ PostgreSQL : pgsql / contrib / dblink / dblink . c , v 1.74 2008 / 07 / 03 03 : 56 : 57 joe Exp $
* Copyright ( c ) 2001 - 2008 , PostgreSQL Global Development Group
* ALL RIGHTS RESERVED ;
*
@ -94,6 +94,7 @@ static HeapTuple get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 p
static Oid get_relid_from_relname ( text * relname_text ) ;
static char * generate_relation_name ( Oid relid ) ;
static void dblink_security_check ( PGconn * conn , remoteConn * rconn ) ;
static void dblink_res_error ( const char * conname , PGresult * res , const char * dblink_context_msg , bool fail ) ;
/* Global */
static remoteConn * pconn = NULL ;
@ -125,34 +126,20 @@ typedef struct remoteConnHashEnt
} \
} while ( 0 )
# define DBLINK_RES_INTERNALERROR(p2) \
do { \
msg = pstrdup ( PQerrorMessage ( conn ) ) ; \
if ( res ) \
PQclear ( res ) ; \
elog ( ERROR , " %s: %s " , p2 , msg ) ; \
} while ( 0 )
# define DBLINK_RES_ERROR(p2) \
# define xpstrdup(var_c, var_) \
do { \
msg = pstrdup ( PQerrorMessage ( conn ) ) ; \
if ( res ) \
PQclear ( res ) ; \
ereport ( ERROR , \
( errcode ( ERRCODE_SYNTAX_ERROR ) , \
errmsg ( " %s " , p2 ) , \
errdetail ( " %s " , msg ) ) ) ; \
if ( var_ ! = NULL ) \
var_c = pstrdup ( var_ ) ; \
else \
var_c = NULL ; \
} while ( 0 )
# define DBLINK_RES_ERROR_AS_NOTICE (p2) \
# define DBLINK_RES_INTERNALERROR(p2) \
do { \
msg = pstrdup ( PQerrorMessage ( conn ) ) ; \
if ( res ) \
PQclear ( res ) ; \
ereport ( NOTICE , \
( errcode ( ERRCODE_SYNTAX_ERROR ) , \
errmsg ( " %s " , p2 ) , \
errdetail ( " %s " , msg ) ) ) ; \
elog ( ERROR , " %s: %s " , p2 , msg ) ; \
} while ( 0 )
# define DBLINK_CONN_NOT_AVAIL \
@ -396,13 +383,8 @@ dblink_open(PG_FUNCTION_ARGS)
res = PQexec ( conn , buf . data ) ;
if ( ! res | | PQresultStatus ( res ) ! = PGRES_COMMAND_OK )
{
if ( fail )
DBLINK_RES_ERROR ( " sql error " ) ;
else
{
DBLINK_RES_ERROR_AS_NOTICE ( " sql error " ) ;
PG_RETURN_TEXT_P ( cstring_to_text ( " ERROR " ) ) ;
}
dblink_res_error ( conname , res , " could not open cursor " , fail ) ;
PG_RETURN_TEXT_P ( cstring_to_text ( " ERROR " ) ) ;
}
PQclear ( res ) ;
@ -470,13 +452,8 @@ dblink_close(PG_FUNCTION_ARGS)
res = PQexec ( conn , buf . data ) ;
if ( ! res | | PQresultStatus ( res ) ! = PGRES_COMMAND_OK )
{
if ( fail )
DBLINK_RES_ERROR ( " sql error " ) ;
else
{
DBLINK_RES_ERROR_AS_NOTICE ( " sql error " ) ;
PG_RETURN_TEXT_P ( cstring_to_text ( " ERROR " ) ) ;
}
dblink_res_error ( conname , res , " could not close cursor " , fail ) ;
PG_RETURN_TEXT_P ( cstring_to_text ( " ERROR " ) ) ;
}
PQclear ( res ) ;
@ -513,7 +490,6 @@ dblink_fetch(PG_FUNCTION_ARGS)
int call_cntr ;
int max_calls ;
AttInMetadata * attinmeta ;
char * msg ;
PGresult * res = NULL ;
MemoryContext oldcontext ;
char * conname = NULL ;
@ -590,13 +566,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
( PQresultStatus ( res ) ! = PGRES_COMMAND_OK & &
PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) )
{
if ( fail )
DBLINK_RES_ERROR ( " sql error " ) ;
else
{
DBLINK_RES_ERROR_AS_NOTICE ( " sql error " ) ;
SRF_RETURN_DONE ( funcctx ) ;
}
dblink_res_error ( conname , res , " could not fetch from cursor " , fail ) ;
SRF_RETURN_DONE ( funcctx ) ;
}
else if ( PQresultStatus ( res ) = = PGRES_COMMAND_OK )
{
@ -846,15 +817,10 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
( PQresultStatus ( res ) ! = PGRES_COMMAND_OK & &
PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) )
{
if ( fail )
DBLINK_RES_ERROR ( " sql error " ) ;
else
{
DBLINK_RES_ERROR_AS_NOTICE ( " sql error " ) ;
if ( freeconn )
PQfinish ( conn ) ;
SRF_RETURN_DONE ( funcctx ) ;
}
dblink_res_error ( conname , res , " could not execute query " , fail ) ;
if ( freeconn )
PQfinish ( conn ) ;
SRF_RETURN_DONE ( funcctx ) ;
}
if ( PQresultStatus ( res ) = = PGRES_COMMAND_OK )
@ -1180,10 +1146,7 @@ dblink_exec(PG_FUNCTION_ARGS)
( PQresultStatus ( res ) ! = PGRES_COMMAND_OK & &
PQresultStatus ( res ) ! = PGRES_TUPLES_OK ) )
{
if ( fail )
DBLINK_RES_ERROR ( " sql error " ) ;
else
DBLINK_RES_ERROR_AS_NOTICE ( " sql error " ) ;
dblink_res_error ( conname , res , " could not execute command " , fail ) ;
/* need a tuple descriptor representing one TEXT column */
tupdesc = CreateTemplateTupleDesc ( 1 , false ) ;
@ -1195,7 +1158,6 @@ dblink_exec(PG_FUNCTION_ARGS)
* result tuple
*/
sql_cmd_status = cstring_to_text ( " ERROR " ) ;
}
else if ( PQresultStatus ( res ) = = PGRES_COMMAND_OK )
{
@ -2288,3 +2250,54 @@ dblink_security_check(PGconn *conn, remoteConn *rconn)
}
}
}
static void
dblink_res_error ( const char * conname , PGresult * res , const char * dblink_context_msg , bool fail )
{
int level ;
char * pg_diag_sqlstate = PQresultErrorField ( res , PG_DIAG_SQLSTATE ) ;
char * pg_diag_message_primary = PQresultErrorField ( res , PG_DIAG_MESSAGE_PRIMARY ) ;
char * pg_diag_message_detail = PQresultErrorField ( res , PG_DIAG_MESSAGE_DETAIL ) ;
char * pg_diag_message_hint = PQresultErrorField ( res , PG_DIAG_MESSAGE_HINT ) ;
char * pg_diag_context = PQresultErrorField ( res , PG_DIAG_CONTEXT ) ;
int sqlstate ;
char * message_primary ;
char * message_detail ;
char * message_hint ;
char * message_context ;
const char * dblink_context_conname = " unnamed " ;
if ( fail )
level = ERROR ;
else
level = NOTICE ;
if ( pg_diag_sqlstate )
sqlstate = MAKE_SQLSTATE ( pg_diag_sqlstate [ 0 ] ,
pg_diag_sqlstate [ 1 ] ,
pg_diag_sqlstate [ 2 ] ,
pg_diag_sqlstate [ 3 ] ,
pg_diag_sqlstate [ 4 ] ) ;
else
sqlstate = ERRCODE_CONNECTION_FAILURE ;
xpstrdup ( message_primary , pg_diag_message_primary ) ;
xpstrdup ( message_detail , pg_diag_message_detail ) ;
xpstrdup ( message_hint , pg_diag_message_hint ) ;
xpstrdup ( message_context , pg_diag_context ) ;
if ( res )
PQclear ( res ) ;
if ( conname )
dblink_context_conname = conname ;
ereport ( level ,
( errcode ( sqlstate ) ,
message_primary ? errmsg ( " %s " , message_primary ) : errmsg ( " unknown error " ) ,
message_detail ? errdetail ( " %s " , message_detail ) : 0 ,
message_hint ? errhint ( " %s " , message_hint ) : 0 ,
message_context ? errcontext ( " %s " , message_context ) : 0 ,
errcontext ( " Error occurred on dblink connection named \" %s \" : %s. " ,
dblink_context_conname , dblink_context_msg ) ) ) ;
}