@@ -884,7 +884,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
884884 Portal portal = NULL ;
885885 DestReceiver * receiver = NULL ;
886886 QueryCompletion qc ;
887- uint64 processed = 0 ;
888887 ListCell * lc ;
889888 List * param_data_buffers = NIL ; /* Track parameter buffers for deferred cleanup */
890889
@@ -913,15 +912,15 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
913912 stmt -> schema_name ? stmt -> schema_name : "dbo" ,
914913 stmt -> proc_name );
915914
916- elog ( LOG , "DEBUG_LINKED_SERVER: (RPC) - Executing procedure: %s" , full_proc_name );
915+ LINKED_SERVER_DEBUG ( " Executing remote procedure: %s" , full_proc_name );
917916
918917 PG_TRY ();
919918 {
920919 /*
921920 * PHASE 1: Validate procedure contains only SELECT statements
922921 * This will establish a temporary connection, fetch the definition, validate it, and close
923922 */
924- elog ( LOG , "SELECT-only validation: Validating procedure %s" , full_proc_name );
923+ LINKED_SERVER_DEBUG ( "SELECT-only validation: Validating procedure %s" , full_proc_name );
925924
926925 /* Temporarily establish connection just for validation */
927926 linked_server_establish_connection (stmt -> server_name , & validation_lsproc , false);
@@ -935,14 +934,12 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
935934 /* Validation connection has been closed internally - mark as cleaned up */
936935 validation_lsproc = NULL ;
937936
938- elog (LOG , "SELECT-only validation: Procedure %s passed validation" , full_proc_name );
939937
940938 /*
941939 * PHASE 2: Open fresh TDS connection for RPC execution
942940 * Clean connection with no SQL query history
943941 */
944942 Assert (lsproc == NULL ); /* Sanity check - RPC connection must be clean */
945- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - Opening fresh connection for RPC" );
946943 linked_server_establish_connection (stmt -> server_name , & lsproc , false);
947944
948945 /* Initialize RPC call on clean connection */
@@ -951,7 +948,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
951948 (errcode (ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION ),
952949 errmsg ("Failed to initialize RPC call for procedure %s" , full_proc_name )));
953950
954- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - RPC call initialized, binding parameters" );
955951
956952 /* Bind each parameter */
957953 foreach (lc , stmt -> params )
@@ -974,8 +970,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
974970 tds_type = get_tds_type_from_pg_oid (valtype );
975971
976972 /* DEBUG: Log before conversion */
977- elog (LOG , "DEBUG_RPC_PARAM: Converting parameter: name=%s, pg_type_oid=%u, tds_type=%d" ,
978- p -> name ? p -> name : "(positional)" , valtype , tds_type );
979973
980974 /* Convert Datum to raw bytes */
981975 convert_datum_to_tds_bytes (val , valtype , valtypmod , isnull ,
@@ -1003,22 +997,9 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
1003997 }
1004998
1005999 /* DEBUG: Log parameter details before dbrpcparam call */
1006- elog ( LOG , "DEBUG_RPC_PARAM: Binding parameter : name=%s, tds_type=%d, maxlen=%d, len=%d, isnull=%d" ,
1000+ LINKED_SERVER_DEBUG_FINER ( "RPC param : name=%s, tds_type=%d, maxlen=%d, len=%d, isnull=%d" ,
10071001 p -> name ? p -> name : "(positional)" , tds_type , maxlen , param_len , isnull );
10081002
1009- /* Log first bytes if data present */
1010- if (param_data && param_len > 0 )
1011- {
1012- int bytes_to_show = (param_len < 20 ) ? param_len : 20 ;
1013- StringInfoData hex_dump ;
1014- initStringInfo (& hex_dump );
1015- for (int i = 0 ; i < bytes_to_show ; i ++ )
1016- {
1017- appendStringInfo (& hex_dump , "%02x " , ((unsigned char * )param_data )[i ]);
1018- }
1019- elog (LOG , "DEBUG_RPC_PARAM: Parameter data first %d bytes (hex): %s" , bytes_to_show , hex_dump .data );
1020- pfree (hex_dump .data );
1021- }
10221003
10231004 /* Bind the parameter */
10241005 if (LINKED_SERVER_RPC_PARAM (lsproc ,
@@ -1046,15 +1027,13 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
10461027 param_data_buffers = lappend (param_data_buffers , param_data );
10471028 }
10481029
1049- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - All parameters bound, sending RPC call" );
10501030
10511031 /* Send the RPC call */
10521032 if (LINKED_SERVER_RPC_SEND (lsproc ) != SUCCEED )
10531033 ereport (ERROR ,
10541034 (errcode (ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION ),
10551035 errmsg ("Failed to send RPC call for procedure %s" , full_proc_name )));
10561036
1057- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - RPC call sent, data transmitted to server" );
10581037
10591038 /*
10601039 * NOW it's safe to free parameter data buffers - dbrpcsend() has transmitted the data.
@@ -1071,7 +1050,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
10711050 }
10721051 list_free (param_data_buffers );
10731052 param_data_buffers = NIL ;
1074- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - Parameter buffers freed after RPC send" );
10751053 }
10761054
10771055 /* Execute the RPC */
@@ -1080,7 +1058,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
10801058 (errcode (ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION ),
10811059 errmsg ("Failed to execute remote procedure %s" , full_proc_name )));
10821060
1083- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - Remote procedure executed successfully" );
10841061
10851062 /* Get first result set (procedures may return multiple result sets) */
10861063 if ((erc = LINKED_SERVER_RESULTS (lsproc )) != NO_MORE_RESULTS )
@@ -1098,7 +1075,7 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
10981075 void * val [MAX_COLS_SELECT ];
10991076
11001077 /* Procedure returned a result set */
1101- elog ( LOG , "DEBUG_LINKED_SERVER: ( RPC) - Result set with %d columns" , colcount );
1078+ LINKED_SERVER_DEBUG ( "Remote RPC result set with %d columns" , colcount );
11021079
11031080 /* Build TupleDesc from column metadata */
11041081 tupdesc = CreateTemplateTupleDesc (colcount );
@@ -1149,7 +1126,7 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
11491126 pfree (nulls );
11501127 }
11511128
1152- elog ( LOG , "DEBUG_LINKED_SERVER: ( RPC) - Fetched %d rows" , rowcount );
1129+ LINKED_SERVER_DEBUG ( "Remote RPC fetched %d rows" , rowcount );
11531130
11541131 /* Finalize tuplestore */
11551132 tuplestore_donestoring (tupstore );
@@ -1173,16 +1150,14 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
11731150 receiver = CreateDestReceiver (DestRemote );
11741151 SetRemoteDestReceiverParams (receiver , portal );
11751152
1176- if (PortalRun (portal ,
1177- FETCH_ALL ,
1178- true,
1179- true,
1180- receiver ,
1181- receiver ,
1182- & qc ))
1183- processed = portal -> portalPos ;
1153+ PortalRun (portal ,
1154+ FETCH_ALL ,
1155+ true,
1156+ true,
1157+ receiver ,
1158+ receiver ,
1159+ & qc );
11841160
1185- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - Sent %d rows to client" , (int )processed );
11861161
11871162 receiver -> rDestroy (receiver );
11881163
@@ -1213,7 +1188,7 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
12131188 ListCell * lc_out ;
12141189 int param_idx ;
12151190
1216- elog ( LOG , "DEBUG_LINKED_SERVER: (RPC) - Retrieving %d OUTPUT parameter values" , num_rets );
1191+ LINKED_SERVER_DEBUG ( " Retrieving %d OUTPUT parameter values" , num_rets );
12171192
12181193 /*
12191194 * Iterate through the stmt->params list to find OUTPUT parameters
@@ -1251,7 +1226,7 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
12511226 int ret_len = LINKED_SERVER_RET_LEN (lsproc , ret_idx );
12521227 int ret_type = LINKED_SERVER_RET_TYPE (lsproc , ret_idx );
12531228
1254- elog ( LOG , "DEBUG_LINKED_SERVER: (RPC) - OUTPUT param %s: type=%d, len=%d, data=%s" ,
1229+ LINKED_SERVER_DEBUG_FINER ( " OUTPUT param %s: type=%d, len=%d, data=%s" ,
12551230 p -> name ? p -> name : "(positional)" ,
12561231 ret_type , ret_len ,
12571232 ret_data ? "present" : "NULL" );
@@ -1300,15 +1275,22 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
13001275 exec_set_rowcount (rowcount );
13011276 exec_set_found (estate , rowcount != 0 );
13021277
1303- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - Remote procedure execution completed successfully" );
1278+ /*
1279+ * PHASE 4: Capture the remote procedure's return status.
1280+ * In TDS protocol, dbretstatus() returns the RETURN value from the
1281+ * remote stored procedure (the value in "RETURN <n>").
1282+ * Store it in pltsql_proc_return_code so the caller can read it.
1283+ */
1284+ pltsql_proc_return_code = LINKED_SERVER_RET_STATUS (lsproc );
1285+
1286+ LINKED_SERVER_DEBUG ("Remote procedure completed, return status=%d" , pltsql_proc_return_code );
13041287 }
13051288 PG_FINALLY ();
13061289 {
13071290 /* Clean up parameter buffers if error occurred before RPC send completed */
13081291 if (param_data_buffers != NIL )
13091292 {
13101293 ListCell * buf_cell ;
1311- elog (LOG , "DEBUG_LINKED_SERVER: (CLEANUP) - Freeing parameter buffers in error path" );
13121294 foreach (buf_cell , param_data_buffers )
13131295 {
13141296 void * buf = lfirst (buf_cell );
@@ -1322,7 +1304,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
13221304 /* Clean up validation connection if error occurred during validation */
13231305 if (validation_lsproc )
13241306 {
1325- elog (LOG , "DEBUG_LINKED_SERVER: (CLEANUP) - Closing validation connection" );
13261307 LINKED_SERVER_CANCEL (validation_lsproc );
13271308 LINKED_SERVER_CLOSE (validation_lsproc );
13281309 validation_lsproc = NULL ;
@@ -1331,7 +1312,6 @@ execute_remote_procedure_rpc(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
13311312 /* Clean up RPC connection if error occurred during RPC */
13321313 if (lsproc )
13331314 {
1334- elog (LOG , "DEBUG_LINKED_SERVER: (RPC) - Closing connection" );
13351315 LINKED_SERVER_CANCEL (lsproc );
13361316 LINKED_SERVER_CLOSE (lsproc );
13371317 lsproc = NULL ;
@@ -1367,11 +1347,6 @@ exec_stmt_exec(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
13671347 * Check if this is a remote procedure call via linked server.
13681348 * If server_name is set, this is a 4-part name like: server.db.schema.proc
13691349 */
1370- elog (LOG , "DEBUG_REMOTE_EXEC: Checking server_name - value: %s, db_name: %s, schema_name: %s, proc_name: %s" ,
1371- stmt -> server_name ? stmt -> server_name : "NULL" ,
1372- stmt -> db_name ? stmt -> db_name : "NULL" ,
1373- stmt -> schema_name ? stmt -> schema_name : "NULL" ,
1374- stmt -> proc_name ? stmt -> proc_name : "NULL" );
13751350
13761351 if (stmt -> server_name != NULL )
13771352 {
@@ -1396,7 +1371,6 @@ exec_stmt_exec(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
13961371 errhint ("Execute: EXEC sp_serveroption '%s', 'rpc out', 'true'" ,
13971372 stmt -> server_name )));
13981373
1399- elog (LOG , "DEBUG_REMOTE_EXEC: RPC out is enabled, proceeding with remote execution for server: %s" , stmt -> server_name );
14001374
14011375 /* Execute remote procedure using secure TDS RPC parameter binding */
14021376#ifdef ENABLE_TDS_LIB
@@ -1409,8 +1383,8 @@ exec_stmt_exec(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
14091383 if (stmt -> return_code_dno >= 0 )
14101384 {
14111385 PLtsql_var * return_code = (PLtsql_var * ) estate -> datums [stmt -> return_code_dno ];
1412- /* Set return code to 0 (success) for now */
1413- exec_assign_value (estate , (PLtsql_datum * ) return_code , Int32GetDatum (0 ), false, INT4OID , 0 );
1386+ /* Use the actual return status from the remote procedure (set by execute_remote_procedure_rpc) */
1387+ exec_assign_value (estate , (PLtsql_datum * ) return_code , Int32GetDatum (pltsql_proc_return_code ), false, INT4OID , 0 );
14141388 }
14151389
14161390 return remote_rc ;
@@ -1424,7 +1398,6 @@ exec_stmt_exec(PLtsql_execstate *estate, PLtsql_stmt_exec *stmt)
14241398#endif
14251399 }
14261400
1427- elog (LOG , "DEBUG_REMOTE_EXEC: Taking LOCAL execution path (server_name is NULL)" );
14281401
14291402 /*
14301403 * We need to disable the explain gucs incase of sp_reset_connection
0 commit comments