Re: Largeobject Access Controls (r2460) - Mailing list pgsql-hackers

From KaiGai Kohei
Subject Re: Largeobject Access Controls (r2460)
Date
Msg-id 4B231667.2080305@kaigai.gr.jp
Whole thread Raw
In response to Re: Largeobject Access Controls (r2460)  (Takahiro Itagaki <itagaki.takahiro@oss.ntt.co.jp>)
Responses Re: Largeobject Access Controls (r2460)  (Takahiro Itagaki <itagaki.takahiro@oss.ntt.co.jp>)
List pgsql-hackers
Takahiro Itagaki wrote:
> KaiGai Kohei <kaigai@ak.jp.nec.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_largeobjectWHERE 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@kaigai.gr.jp>


pgsql-hackers by date:

Previous
From: Euler Taveira de Oliveira
Date:
Subject: Re: Need a mentor, and a project.
Next
From: Tom Lane
Date:
Subject: Re: [GENERAL] Installing PL/pgSQL by default