Fix postgresql_fdw to support oid system column.
authorShigeru Hanada <[email protected]>
Thu, 18 Nov 2010 11:33:39 +0000 (20:33 +0900)
committerShigeru Hanada <[email protected]>
Fri, 19 Nov 2010 01:49:31 +0000 (10:49 +0900)
contrib/postgresql_fdw/expected/postgresql_fdw.out
contrib/postgresql_fdw/postgresql_fdw.c
contrib/postgresql_fdw/sql/postgresql_fdw.sql

index 34687925fbdf3309618846769f63a24fc5f5feba..c372a8f8afe5222335dea4089cecddcc5b0d48f3 100644 (file)
@@ -22,7 +22,7 @@ CREATE TABLE t1(
    c1 integer,
    c2 text,
    c3 date
-);
+) WITH OIDS;
 COPY t1 FROM stdin;
 CREATE TABLE t2(
    c1 integer,
@@ -34,7 +34,7 @@ CREATE FOREIGN TABLE ft1 (
    c1 integer OPTIONS (colname 'invalid'),
    c2 text OPTIONS (colname 'C2'),
    c3 date
-) SERVER loopback1 OPTIONS (relname 't1');
+) SERVER loopback1 WITH OIDS OPTIONS (relname 't1');
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (SET colname 'C1');
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c2 OPTIONS (DROP colname);
 CREATE FOREIGN TABLE ft2 (
@@ -43,7 +43,7 @@ CREATE FOREIGN TABLE ft2 (
    c3 date
 ) SERVER loopback2 OPTIONS (relname 'invalid');
 -- simple query and connection caching
-SELECT * FROM ft1 ORDER BY c1;
+SELECT ft1.* FROM ft1 JOIN t1 ON ((t1.c1, t1.oid) = (ft1.c1, ft1.oid)) ORDER BY c1;
  c1 | c2  |     c3     
 ----+-----+------------
   1 | foo | 01-01-1970
@@ -100,7 +100,7 @@ SELECT * FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY 1,2,3,4,5,6;
 -- WHERE clause push-down
 set client_min_messages = debug1;
 SELECT * FROM ft1 WHERE c1 = 1 AND c2 = lower('FOO') AND c3 < now();
-DEBUG:  deparsed SQL is "SELECT C1, c2, c3 FROM public.t1 ft1 WHERE ((c1 = 1) AND (c2 = 'foo'::text))"
+DEBUG:  deparsed SQL is "SELECT C1, c2, c3, oid FROM public.t1 ft1 WHERE ((c1 = 1) AND (c2 = 'foo'::text))"
  c1 | c2  |     c3     
 ----+-----+------------
   1 | foo | 01-01-1970
index 16cfe150d9449896ab61778ae2312beca73778bf..40ceef03f2de175d50ffc7cd94b069e521025c8e 100644 (file)
@@ -300,6 +300,16 @@ deparseSelectClause(StringInfo sql, ForeignTable *table, TupleDesc tupdesc,
        first = false;
    }
 
+   /* Add oid system attribute if any on local side. */
+   if (tupdesc->tdhasoid)
+   {
+       if (!first)
+           appendStringInfo(sql, ", oid");
+       else
+           appendStringInfo(sql, "oid");
+       first = false;
+   }
+
    /* if target list is composed only of system attributes, add dummy column */
    if (first)
        appendStringInfoString(sql, "NULL");
@@ -679,6 +689,8 @@ storeResult(Tuplestorestate *tupstore,
    for (attnum = 0, i = 0; i < tupdesc->natts; i++)
        if (!attrs[i]->attisdropped)
            attnum++;
+   if (tupdesc->tdhasoid)
+       attnum++;
 
    /* check result and tuple descriptor have the same number of columns */
    if (attnum > 0 && attnum != nfields)
@@ -696,6 +708,7 @@ storeResult(Tuplestorestate *tupstore,
    {
        int         j;
        HeapTuple   tuple;
+       Oid         oid = InvalidOid;       /* oid of the tuple */
 
        CHECK_FOR_INTERRUPTS();
 
@@ -716,14 +729,26 @@ storeResult(Tuplestorestate *tupstore,
                    values[i] = PQgetvalue(res, row, j);
                j++;
            }
+
+           /* Get oid if any.  Now j points the oid field of PGresult. */
+           if (tupdesc->tdhasoid)
+           {
+               if (!PQgetisnull(res, row, j))
+               {
+                   oid = DatumGetObjectId(DirectFunctionCall1(oidin,
+                               CStringGetDatum(PQgetvalue(res, row, j))));
+               }
+           }
        }
        else
        {
            values[0] = PQcmdStatus(res);
        }
 
-       /* build the tuple and put it into the tuplestore. */
+       /* build the tuple, set oid if any, and put it into the tuplestore. */
        tuple = BuildTupleFromCStrings(attinmeta, values);
+       if (tupdesc->tdhasoid)
+           HeapTupleSetOid(tuple, oid);
        tuplestore_puttuple(tupstore, tuple);
    }
 
index 0bdcff2700e491a0f7b053bc7b31557c3e341997..8d918aed194ee8b7a0c0239c59a9975056b7b9fb 100644 (file)
@@ -30,7 +30,7 @@ CREATE TABLE t1(
    c1 integer,
    c2 text,
    c3 date
-);
+) WITH OIDS;
 
 COPY t1 FROM stdin;
 1  foo 1970-01-01
@@ -54,7 +54,7 @@ CREATE FOREIGN TABLE ft1 (
    c1 integer OPTIONS (colname 'invalid'),
    c2 text OPTIONS (colname 'C2'),
    c3 date
-) SERVER loopback1 OPTIONS (relname 't1');
+) SERVER loopback1 WITH OIDS OPTIONS (relname 't1');
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (SET colname 'C1');
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c2 OPTIONS (DROP colname);
 
@@ -65,7 +65,7 @@ CREATE FOREIGN TABLE ft2 (
 ) SERVER loopback2 OPTIONS (relname 'invalid');
 
 -- simple query and connection caching
-SELECT * FROM ft1 ORDER BY c1;
+SELECT ft1.* FROM ft1 JOIN t1 ON ((t1.c1, t1.oid) = (ft1.c1, ft1.oid)) ORDER BY c1;
 SELECT * FROM ft2 ORDER BY c1; -- ERROR
 ALTER USER MAPPING FOR PUBLIC SERVER loopback2 OPTIONS (DROP user);
 SELECT * FROM ft2 ORDER BY c1; -- ERROR