簡體   English   中英

如何在Postgresql C語言函數中訪問大對象?

[英]How to access large objects in Postgresql c-language functions?

我正在為Postgresql 9.3.5寫一個c語言用戶定義的函數。 我沒有使用pl / pgsql或pl / python,因為其中的一部分需要用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();
}

更新:這似乎是一個示例:

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

這是一個主意

#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();
}

您需要閱讀有關SPI_tubtable指針的信息,以了解如何解析查詢以及整個SPI Server編程接口

由於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 *函數的許多示例可以在此處此處找到

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM