了解从 bytea 到 oid 的转换
Understanding cast from bytea to oid
我正在使用 PostgreSQL 9.2
。
This blog entry by Grace Batumbya 提供从 bytea
到 oid
的转换。
create or replace function blob_write(lbytea bytea)
returns oid
volatile
language plpgsql as
$f$
declare
loid oid;
lfd integer;
lsize integer;
begin
if(lbytea is null) then
return null;
end if;
loid := lo_create(0);
lfd := lo_open(loid,131072);
lsize := lowrite(lfd,lbytea);
perform lo_close(lfd);
return loid;
end;
$f$;
CREATE CAST (bytea AS oid) WITH FUNCTION blob_write(bytea) AS ASSIGNMENT;
CREATE TABLE bytea_to_lo (
largeObj lo
);
我不明白为什么要创建bytea_to_lo
table? PostgreSQL
将如何使用它?
该演员不是真正的演员。它只是(ab)使用方便的语法。后台创建一个large object (LO)单独存储,返回引用它的OID
All large objects are stored in a single system table named
pg_largeobject
. Each large object also has an entry in the system
table pg_largeobject_metadata
. Large objects can be created, modified,
and deleted using a read/write API that is similar to standard
operations on files.
返回的OID基本上是FK对系统PK的FKtablepg_largeobject
.
CREATE TABLE
完全独立于函数和伪投。
CREATE TABLE bytea_to_lo (
largeObj lo
);
这只是上面创建的赋值转换的典型用例,从您忘记引用的以下行中可以看出这一点:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
这里发生了什么?
数据类型 lo
是基本类型 oid
的域,由附加模块 lo
(incorrectly referenced as "lo_manage package" in the blog enty of Grace Batumbya). Per documentation:
创建
The module also provides a data type lo
, which is really just a domain
of the oid
type. This is useful for differentiating database columns
that hold large object references from those that are OIDs of other things.
函数decode()
returnsbytea
。 INSERT
语句将 bytea
值分配给列 largeObj
,这会触发对其类型 lo
的赋值转换,这就是上述转换的用武之地。
警告/更正/更新
博客条目草率且过时。
懒得提那个(per documentation):
To be able to create a cast, you must own the source or the target
data type and have USAGE
privilege on the other type.
实际上,您必须是超级用户。
CREATE TABLE
中的拼写错误:列名和类型颠倒了。
函数定义冗长且效率低下。这会更好(对于 Postgres 9.3 或更早版本):
CREATE OR REPLACE FUNCTION blob_write(bytea)
RETURNS oid AS
$func$
DECLARE
loid oid := lo_create(0);
lfd int := lo_open(loid,131072); -- = 2^17 = x2000
-- symbolic constant defined in the header file libpq/libpq-fs.h
-- #define INV_WRITE 0x00020000
BEGIN
PERFORM lowrite(lfd, );
PERFORM lo_close(lfd);
RETURN loid;
END
$func$ LANGUAGE plpgsql VOLATILE STRICT;
在 Postgres 9.4 中有一个 built-in function。改用它:
lo_from_bytea(loid oid, string bytea)
- Add SQL functions to allow large object reads/writes at arbitrary offsets (Pavel Stehule)
对于CREATE CAST
(per documentation):
The first argument type must be identical to or binary-coercible from the cast's source type.
我建议使用只有一个 bytea
参数的重载变体:
CREATE OR REPLACE FUNCTION lo_from_bytea(bytea)
RETURNS oid LANGUAGE sql AS
'SELECT lo_from_bytea(0, )';
CREATE CAST (bytea AS oid) WITH FUNCTION lo_from_bytea(bytea) AS ASSIGNMENT;
由于伪演员有相当大的副作用,我不相信将其设为 ASSIGNMENT
演员。我可能会从仅显式开始:
- Generate series of dates - using date type as input
我正在使用 PostgreSQL 9.2
。
This blog entry by Grace Batumbya 提供从 bytea
到 oid
的转换。
create or replace function blob_write(lbytea bytea)
returns oid
volatile
language plpgsql as
$f$
declare
loid oid;
lfd integer;
lsize integer;
begin
if(lbytea is null) then
return null;
end if;
loid := lo_create(0);
lfd := lo_open(loid,131072);
lsize := lowrite(lfd,lbytea);
perform lo_close(lfd);
return loid;
end;
$f$;
CREATE CAST (bytea AS oid) WITH FUNCTION blob_write(bytea) AS ASSIGNMENT;
CREATE TABLE bytea_to_lo (
largeObj lo
);
我不明白为什么要创建bytea_to_lo
table? PostgreSQL
将如何使用它?
该演员不是真正的演员。它只是(ab)使用方便的语法。后台创建一个large object (LO)单独存储,返回引用它的OID
All large objects are stored in a single system table named
pg_largeobject
. Each large object also has an entry in the system tablepg_largeobject_metadata
. Large objects can be created, modified, and deleted using a read/write API that is similar to standard operations on files.
返回的OID基本上是FK对系统PK的FKtablepg_largeobject
.
CREATE TABLE
完全独立于函数和伪投。
CREATE TABLE bytea_to_lo (
largeObj lo
);
这只是上面创建的赋值转换的典型用例,从您忘记引用的以下行中可以看出这一点:
INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
这里发生了什么?
数据类型 lo
是基本类型 oid
的域,由附加模块 lo
(incorrectly referenced as "lo_manage package" in the blog enty of Grace Batumbya). Per documentation:
The module also provides a data type
lo
, which is really just a domain of theoid
type. This is useful for differentiating database columns that hold large object references from those that are OIDs of other things.
函数decode()
returnsbytea
。 INSERT
语句将 bytea
值分配给列 largeObj
,这会触发对其类型 lo
的赋值转换,这就是上述转换的用武之地。
警告/更正/更新
博客条目草率且过时。
懒得提那个(per documentation):
To be able to create a cast, you must own the source or the target data type and have
USAGE
privilege on the other type.实际上,您必须是超级用户。
CREATE TABLE
中的拼写错误:列名和类型颠倒了。函数定义冗长且效率低下。这会更好(对于 Postgres 9.3 或更早版本):
CREATE OR REPLACE FUNCTION blob_write(bytea) RETURNS oid AS $func$ DECLARE loid oid := lo_create(0); lfd int := lo_open(loid,131072); -- = 2^17 = x2000 -- symbolic constant defined in the header file libpq/libpq-fs.h -- #define INV_WRITE 0x00020000 BEGIN PERFORM lowrite(lfd, ); PERFORM lo_close(lfd); RETURN loid; END $func$ LANGUAGE plpgsql VOLATILE STRICT;
在 Postgres 9.4 中有一个 built-in function。改用它:
lo_from_bytea(loid oid, string bytea)
- Add SQL functions to allow large object reads/writes at arbitrary offsets (Pavel Stehule)
对于CREATE CAST
(per documentation):
The first argument type must be identical to or binary-coercible from the cast's source type.
我建议使用只有一个 bytea
参数的重载变体:
CREATE OR REPLACE FUNCTION lo_from_bytea(bytea)
RETURNS oid LANGUAGE sql AS
'SELECT lo_from_bytea(0, )';
CREATE CAST (bytea AS oid) WITH FUNCTION lo_from_bytea(bytea) AS ASSIGNMENT;
由于伪演员有相当大的副作用,我不相信将其设为 ASSIGNMENT
演员。我可能会从仅显式开始:
- Generate series of dates - using date type as input