Postgresql 中文操作指南
35.4. Server-Side Functions #
为从 SQL 操纵大型对象而专门设计的服务器端函数在 Table 35.1中列出。
Server-side functions tailored for manipulating large objects from SQL are listed in Table 35.1.
Table 35.1. SQL-Oriented Large Object Functions
Function Description Example(s) |
lo_from_bytea ( loid oid, data bytea ) → oid Creates a large object and stores data in it. If loid is zero then the system will choose a free OID, otherwise that OID is used (with an error if some large object already has that OID). On success, the large object’s OID is returned. lo_from_bytea(0, '\xffffff00') → 24528 |
lo_put ( loid oid, offset bigint, data bytea ) → void Writes data starting at the given offset within the large object; the large object is enlarged if necessary. lo_put(24528, 1, '\xaa') → |
lo_get ( loid oid [, offset bigint, length integer ] ) → bytea Extracts the large object’s contents, or a substring thereof. lo_get(24528, 0, 3) → \xffaaff |
有其他与前文所述的每个客户端函数相对应的服务器端函数;事实上,客户端函数大多数只是同等服务器端函数的接口。通过 SQL 命令调用起来同样方便的函数包括 lo_creat、lo_create、lo_unlink、lo_import 和 lo_export。以下是一些用例:
There are additional server-side functions corresponding to each of the client-side functions described earlier; indeed, for the most part the client-side functions are simply interfaces to the equivalent server-side functions. The ones just as convenient to call via SQL commands are lo_creat, lo_create, lo_unlink, lo_import, and lo_export. Here are examples of their use:
CREATE TABLE image (
name text,
raster oid
);
SELECT lo_creat(-1); -- returns OID of new, empty large object
SELECT lo_create(43213); -- attempts to create large object with OID 43213
SELECT lo_unlink(173454); -- deletes large object with OID 173454
INSERT INTO image (name, raster)
VALUES ('beautiful image', lo_import('/etc/motd'));
INSERT INTO image (name, raster) -- same as above, but specify OID to use
VALUES ('beautiful image', lo_import('/etc/motd', 68583));
SELECT lo_export(image.raster, '/tmp/motd') FROM image
WHERE name = 'beautiful image';
服务器端 lo_import 和 lo_export 函数的行为与其客户端类似项大不相同。这两个函数使用数据库所有者用户的权限,在服务器文件系统中读取和写入文件。因此,默认情况下,只有超级用户才能使用它们。相比之下,客户端导入和导出函数使用客户端程序的权限在客户端文件系统中读取和写入文件。客户端函数无需任何数据库权限,只需能够读取或写入相关大对象的权限即可。
The server-side lo_import and lo_export functions behave considerably differently from their client-side analogs. These two functions read and write files in the server’s file system, using the permissions of the database’s owning user. Therefore, by default their use is restricted to superusers. In contrast, the client-side import and export functions read and write files in the client’s file system, using the permissions of the client program. The client-side functions do not require any database privileges, except the privilege to read or write the large object in question.
Caution
可以将服务器端 lo_import 和 lo_export 函数的 GRANT 用于非超级用户,但需要仔细考虑安全隐含。此类权限的恶意用户可以轻松地利用它们成为超级用户(例如,通过重写服务器配置文件),或者可以攻击服务器文件系统的其余部分,而不必费心获取数据库超级用户权限。 Access to roles having such privilege must therefore be guarded just as carefully as access to superuser roles. 但是,如果出于某些例行任务需要使用服务器端的 lo_import 或 lo_export ,则使用具有此类权限的角色比使用具有完全超级用户权限的角色更安全,因为这样有助于降低由于偶然错误造成的损坏风险。
It is possible to GRANT use of the server-side lo_import and lo_export functions to non-superusers, but careful consideration of the security implications is required. A malicious user of such privileges could easily parlay them into becoming superuser (for example by rewriting server configuration files), or could attack the rest of the server’s file system without bothering to obtain database superuser privileges as such. Access to roles having such privilege must therefore be guarded just as carefully as access to superuser roles. Nonetheless, if use of server-side lo_import or lo_export is needed for some routine task, it’s safer to use a role with such privileges than one with full superuser privileges, as that helps to reduce the risk of damage from accidental errors.
还可通过服务器端调用使用 lo_read 和 lo_write 的功能,但服务器端函数的名称与客户端接口不同,因为它们不包含下划线。您必须在 loread 和 lowrite 中调用这些函数。
The functionality of lo_read and lo_write is also available via server-side calls, but the names of the server-side functions differ from the client side interfaces in that they do not contain underscores. You must call these functions as loread and lowrite.