Re: Largeobject Access Controls (r2460)

From: KaiGai Kohei <kaigai(at)kaigai(dot)gr(dot)jp>
To: Takahiro Itagaki <itagaki(dot)takahiro(at)oss(dot)ntt(dot)co(dot)jp>
Cc: KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: Largeobject Access Controls (r2460)
Date: 2009-12-12 04:04:55
Message-ID: 4B231667.2080305@kaigai.gr.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Takahiro Itagaki wrote:
> KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com> wrote:
>
>>>> We have to reference pg_largeobject_metadata to check whether a certain
>>>> large objct exists, or not.
>> It is a case when we create a new large object, but write nothing.
>
> OK, that makes sense.
>
> In addition of the patch, we also need to fix pg_restore with
> --clean option. I added DropBlobIfExists() in pg_backup_db.c.
>
> A revised patch attached. Please check further mistakes.

+ void
+ DropBlobIfExists(ArchiveHandle *AH, Oid oid)
+ {
+ const char *lo_relname;
+ const char *lo_colname;
+
+ if (PQserverVersion(AH->connection) >= 80500)
+ {
+ lo_relname = "pg_largeobject_metadata";
+ lo_colname = "oid";
+ }
+ else
+ {
+ lo_relname = "pg_largeobject";
+ lo_colname = "loid";
+ }
+
+ /* Call lo_unlink only if exists to avoid not-found error. */
+ ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.%s WHERE %s = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
+ lo_relname, lo_colname, oid, oid);
+ }

I think the following approach is more reasonable for the current design.

if (PQserverVersion(AH->connection) >= 80500)
{
/* newer query */
ahprintf(AH, "SELECT pg_catalog.lo_unlink(oid) "
"FROM pg_catalog.pg_largeobject_metadata "
"WHERE oid = %u;\n", oid);
}
else
{
/* original query */
ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') "
"THEN pg_catalog.lo_unlink('%u') END;\n", oid, oid);
}

We don't have any reason why still CASE ... WHEN and subquery for the given
LOID. Right?

The fix-lo-contrib.patch looks good for me.

> BTW, we can optimize lo_truncate because we allow metadata-only large
> objects. inv_truncate() doesn't have to update the first data tuple to
> be zero length. It only has to delete all corresponding tuples like as:
> DELETE FROM pg_largeobject WHERE loid = {obj_desc->id}

Right, when inv_truncate takes an aligned length by LOBLKSIZE.

I'll also submit a small patch on CF-Jan, OK?

Thanks,
--
KaiGai Kohei <kaigai(at)kaigai(dot)gr(dot)jp>

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2009-12-12 04:57:03 Re: Installing PL/pgSQL by default
Previous Message Euler Taveira de Oliveira 2009-12-12 04:01:04 Re: Need a mentor, and a project.