The colname option overrides the name of the column in the foreign query.
);
COPY t2 FROM stdin;
CREATE FOREIGN TABLE ft1 (
- c1 integer,
- c2 text,
+ c1 integer OPTIONS (colname 'invalid'),
+ c2 text OPTIONS (colname 'C2'),
c3 date
) SERVER loopback1 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 (
c1 integer,
c2 text,
-- 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 FROM public.t1 ft1 WHERE ((c1 = 1) AND (c2 = 'foo'::text))"
c1 | c2 | c3
----+-----+------------
1 | foo | 01-01-1970
first = true;
for (i = 0; i < tupdesc->natts; i++)
{
+ List *options;
+ ListCell *lc;
+ char *colname = NULL;
+
/* skip dropped attributes */
if (tupdesc->attrs[i]->attisdropped)
continue;
+ /* Determine column name to be used */
+ options = GetGenericOptionsPerColumn(rte->relid, i + 1);
+ foreach (lc, options)
+ {
+ DefElem *def = (DefElem *) lfirst(lc);
+ if (strcmp(def->defname, "colname") == 0)
+ {
+ colname = strVal(def->arg);
+ break;
+ }
+ }
+ if (!colname)
+ colname = tupdesc->attrs[i]->attname.data;
+
if (!first)
appendStringInfoString(&sql, ", ");
if (prefix)
- appendStringInfo(&sql, "%s.%s",
- aliasname_q, tupdesc->attrs[i]->attname.data);
+ appendStringInfo(&sql, "%s.%s", aliasname_q, colname);
else
- appendStringInfo(&sql, "%s", tupdesc->attrs[i]->attname.data);
+ appendStringInfo(&sql, "%s", colname);
+
first = false;
}
\.
CREATE FOREIGN TABLE ft1 (
- c1 integer,
- c2 text,
+ c1 integer OPTIONS (colname 'invalid'),
+ c2 text OPTIONS (colname 'C2'),
c3 date
) SERVER loopback1 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 (
c1 integer,
/* Catalog options */
{"nspname", ForeignTableRelationId, false},
{"relname", ForeignTableRelationId, false},
+ {"colname", AttributeRelationId, false},
/* Planner cost options */
{"connection_cost", ForeignServerRelationId, false},
}
return n;
}
+
+/*
+ * Retrieve per-column generic options in form of DefElem.
+ */
+List *
+GetGenericOptionsPerColumn(Oid relid, int2 attnum)
+{
+ Form_pg_attribute attform;
+ Datum datum;
+ HeapTuple tp;
+ bool isnull;
+ List *options = NIL;
+
+ tp = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum));
+
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for attribute attnum %u of relation %u", (int) attnum, relid);
+
+ attform = (Form_pg_attribute) GETSTRUCT(tp);
+
+ /* Extract the options */
+ datum = SysCacheGetAttr(ATTNUM,
+ tp,
+ Anum_pg_attribute_attgenoptions,
+ &isnull);
+ if (!isnull)
+ options = untransformRelOptions(datum);
+
+ ReleaseSysCache(tp);
+
+ return options;
+}
extern FdwRoutine *GetFdwRoutine(Oid fdwhandler);
extern bool IsForeignTable(Oid relid);
extern Oid GetFdwValidator(Oid relid);
+extern List *GetGenericOptionsPerColumn(Oid relid, int2 attnum);
extern int flatten_generic_options(List *options,
const char **keywords, const char **values);