2015-01-26 45 views
2

我正在爲postgresql 9.3.5編寫一個c-language用戶自定義函數。我沒有使用pl/pgsql或pl/python,因爲它的一部分需要用C語言編寫以提高速度。如何訪問Postgresql c語言函數中的大對象?

該函數獲取現有的OID作爲參數。如何訪問&修改c語言函數中的OID數據?我找不到任何文檔!

我有什麼到目前爲止裏面的功能僅僅是一部分,讀取參數:

#include "postgres.h" 
#include "fmgr.h" 
PG_MODULE_MAGIC; 

Datum tsdb_write_lob(PG_FUNCTION_ARGS) ; 

PG_FUNCTION_INFO_V1(tsdb_write_lob); 



Datum tsdb_write_lob(PG_FUNCTION_ARGS) { 
    int16 arg_dataformat = PG_GETARG_INT16(0); 
    int16 arg_granularity_days = PG_GETARG_INT16(1); 
    Oid arg_dataoid = PG_GETARG_OID(2); 

    ereport(INFO, (errcode(ERRCODE_SUCCESSFUL_COMPLETION), 
       errmsg("Arguments were: %d, %d, %ld\n",arg_dataformat,arg_granularity_days,arg_dataoid))); 


    /*TODO: 
    * open oid (lo_open ?) 
    * read data 
    * decompress data 
    * parse data 
    * add new data 
    * compress data 
    * save to same oid 
    */ 



    PG_RETURN_VOID(); 
} 

UPDATE: 這似乎是一個例子:

https://github.com/postgres/postgres/blob/master/src/backend/libpq/be-fsstubs.c

+0

你能證明你有什麼這麼遠嗎?我真的覺得這非常有趣,最近在c中對PostgreSQL做了一些擴展,所以我可以幫你。 – 2015-01-26 19:07:17

+0

奇怪的是,在開發postgresql函數時,很少有文檔存在。這是運氣和谷歌技能的結合。 – sivann 2015-01-26 19:20:21

+0

是的,在postgresql的文檔中幾乎沒有好的例子。我打算問你,open open oid是什麼意思? – 2015-01-26 19:23:16

回答

0

我找到了一個解決方案,這要歸功於pgsql的郵件列表:

int inv_fd; 
Oid arg_dataoid = PG_GETARG_OID(0); 
... 

//open   
inv_fd = DatumGetInt32(DirectFunctionCall2(lo_open, arg_dataoid, Int32GetDatum(INV_READ|INV_WRITE))); 


if (inv_fd < 0) { 
    elog(ERROR, "lo_open: lookup failed for oid:%ld", DatumGetInt64(arg_dataoid)); 
    PG_RETURN_INT32(-1); 
} 

//write 
if (lo_write(inv_fd, cstr, nbytes) != nbytes) 
     elog(ERROR, "error while writing large object"); 

//close LO 
DirectFunctionCall1(lo_close, Int32GetDatum(inv_fd)); 

很多其他LO *函數的例子可以發現herehere

0

這是一個理念

#include <postgres.h> 
#include <utils/rel.h> 
#include <utils/array.h> 
#include <commands/trigger.h> 
#include <executor/spi.h> 

PG_MODULE_MAGIC; 

Datum tsdb_write_lob(PG_FUNCTION_ARGS) ; 

extern SPITupleTable *SPI_tuptable; 

PG_FUNCTION_INFO_V1(tsdb_write_lob); 
Datum tsdb_write_lob(PG_FUNCTION_ARGS) { 
{ 
    int16 arg_dataformat  = PG_GETARG_INT16(0); 
    int16 arg_granularity_days = PG_GETARG_INT16(1); 
    Oid arg_dataoid   = PG_GETARG_OID(2); 
    char command[128]; 

    if (SPI_ERROR_CONNECT == SPI_connect()) 
     PG_RETURN_VOID(); 
    snprintf(command, sizeof(command), "SELECT lo_open(INV_READ, %d)", arg_dataoid); 
    if (SPI_OK_SELECT != SPI_execute(command, false, 0)) 
     PG_RETURN_VOID(); 
    . 
    . 
    . 
    /* do loread here the same way by using SPI_execute("SELECT loread ...") */ 
    SPI_finish(); 

    PG_RETURN_VOID(); 
} 

您需要r大約有SPI_tubtable指針來找出如何解析查詢,以及整個SPIServer Programming Interface

+0

我現在沒有足夠的時間,但今晚晚些時候我會回來看看它是如何工作的,並儘可能地幫助你。 – 2015-01-26 19:46:57

+0

感謝您的意見。我想解析SQL語句不是很有效率,因爲這個函數被稱爲每秒數千次。 – sivann 2015-01-26 21:30:20

相關問題