Learning postgresql spi (a)

#include "postgres.h"
#include
#include "fmgr.h"
#include "access/xlog.h"
#include "replication/walreceiver.h"
#include "utils/elog.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
#include "funcapi.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "utils / pg_lsn.h " 

#ifdef PG_MODULE_MAGIC 
PG_MODULE_MAGIC; 
#endif 

PG_FUNCTION_INFO_V1 (get_rcv_replication_stat); 

Datum 
get_rcv_replication_stat (PG_FUNCTION_ARGS,) 
{ 
the Assert (PG_NARGS () == 0 ); // means that the input parameter 

IF (! RecoveryInProgress ()) // in the database is running under the recovery state, otherwise, no 
ereport (ERROR, 
(The errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), 
errmsg ( " recovery IS not in Progress " ), 
errhint ( " This Functions CAN BE only the Executed during recovery. " ))); 

/ *Prevent code pointer to volatile use rearrangement * / 
volatile WalRcvData walrcv * = WalRcv; // data structure for managing a shared memory src stream copying / the include / Replication / walreceiver.h 
TupleDesc tupdesc; // Create a row variables describing 
Datum DatumValue [ 8 ]; // create a storage array Datum values, need to return several fields, creating a corresponding length of the array 
BOOL NULLS [ 8 ]; // number of attribute tuples TupleDescData struct typedef -> natts; 

/ * Initialise DatumValue and NULL flags arrays initialization * / 
MemSet (DatumValue, 0 , the sizeof (DatumValue)); 
MemSet (NULLS, 0 , the sizeof(NULLS)); 

/ * Initialise Information Attributes defined in The tuple descriptor field names and field types, the corresponding header file src / include / catalog / pg_type.h find the corresponding type * / 

/ * 
CreateTemplateTupleDesc 
This function allocates an empty tuple descriptor structure. 
Tuple type ID information is initially set to an anonymous record type; 
if required the caller can override this. 

TupleDescInitEntry: This function initializes a single attribute in a tuple structure previously allocated descriptor. 
If attributeName is NULL, attname field will be set to an empty string (this is in case we do not know or do not need the field names). 
Further, some callers use this feature to change a field associated with the prior tupdesc data type; for example, they are passed attributeName = NameStr (att-> attname) should not be modified to indicate attname field. 
Please note, attcollation set to the default value for the specified data type. If you need a non-default collations, use TupleDescInitEntryCollation insert it later. 
* / 
Tupdesc = CreateTemplateTupleDesc ( . 8 , to false  );
TupleDescInitEntry (tupdesc, (AttrNumber)1, "last_walend_time",
TIMESTAMPTZOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_recv_lsn",
LSNOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_apply_lsn",
LSNOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "last_apply_delay_ms",
INT4OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "receiver_pid",
INT4OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 6, "receiver_state",
INT4OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 7, "receiver_start_time",
INT8OID, -1, 0 );
TupleDescInitEntry (tupdesc, (AttrNumber) . 8 , " receiver_conninfo " , 
TEXTOID, - . 1 , 0 ); 
BlessTupleDesc (tupdesc); // complete the construction of the return type, with reference to the src / the include / funcapi.h 

// Next, each converted into a corresponding value stored in the Datum DatumValue array, the array only if the corresponding value nulls empty set to true. 
TimestampTz receipttime; 
receipttime = walrcv-> latestWalEndTime;     // TimestampTz latestWalEndTime; 
DatumValue [ 0 ] = TimestampTzGetDatum (receipttime) ;     // #define TimestampTzGetDatum (the X-) Int64GetDatum (the X-) 
XLogRecPtr recvPtr;     //src / include / access / xlogdefs.h pointer position in XLOG. These pointers are 64 bits wide, because we do not want them to overflow. 

/ * 
The src / backend / Replication / walreceiverfuncs.c: GetWalRcvWriteRecPtr 
returns the last byte has been written to a position walreceiver. 
(Optional) to return to the beginning of a block, i.e., the refresh cycle of the first byte written in recent walreceiver. The caller is not interested in the value NULL can be passed to lastChunkStart. And receiveTLI same. 
* / 
RecvPtr = GetWalRcvWriteRecPtr (NULL, NULL);     // XLogRecPtr recptr; 
IF (recvPtr == 0 ) 
NULLS [ . 1 ] = to true ;
 the else 
DatumValue [ . 1 ] = LSNGetDatum (recvPtr);     // #define LSNGetDatum (X-) ( Int64GetDatum ((int64) (the X-))) 


/ *  
xlog.c: GetXLogReplayRecPtr
Get the latest redo apply position. 
WALReceiver directly exported to allow a read pointer. 

* / 
XLogRecPtr applyPtr; 
applyPtr = GetXLogReplayRecPtr (NULL);
 IF (recvPtr == 0 ) 
NULLS [ 2 ] = to true ;
 the else 
DatumValue [ 2 ] = LSNGetDatum (applyPtr);
 int apply_delay_ms; 

/ * 
walreceiverfuncs.c: GetReplicationApplyDelay 
If no application delay information, the copy application returns the delay (in milliseconds) or -1 
* / 
apply_delay_ms = GetReplicationApplyDelay ();
 IF (apply_delay_ms == - . 1 ) 
NULLS [ . 3 ] = to true ;
else
DatumValue[3] = Int32GetDatum(apply_delay_ms);
DatumValue[4] = Int32GetDatum(walrcv->pid);
DatumValue[5] = Int32GetDatum(walrcv->walRcvState);
DatumValue[6] = Int64GetDatum(walrcv->startTime);
DatumValue[7] = PointerGetDatum(cstring_to_text((char *)walrcv->conninfo));
// 返回
/* Returns the record as Datum 把元组变成 datum */
PG_RETURN_DATUM(HeapTupleGetDatum( heap_form_tuple(tupdesc, DatumValue, nulls)));    //heap_form_tuple configured tuple and returns a HeapTupleHeader, HeapTupleGetDatum converted HeapTupleHeader pointer Datum. 

}

Guess you like

Origin www.cnblogs.com/kelvin19840813/p/12210308.html
SPI