From: | Andres Freund <andres(at)anarazel(dot)de> |
---|---|
To: | Paul Ramsey <pramsey(at)cleverelephant(dot)ca> |
Cc: | Simon Riggs <simon(at)2ndquadrant(dot)com>, Michael Paquier <michael(dot)paquier(at)gmail(dot)com>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: [PATCH] postgres_fdw extension support |
Date: | 2015-07-21 14:45:01 |
Message-ID: | 20150721144501.GD13636@awork2.anarazel.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
On 2015-07-21 07:28:22 -0700, Paul Ramsey wrote:
> /*
> @@ -229,6 +236,9 @@ foreign_expr_walker(Node *node,
> Oid collation;
> FDWCollateState state;
>
> + /* Access extension metadata from fpinfo on baserel */
> + PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *)(glob_cxt->foreignrel->fdw_private);
> +
> /* Need do nothing for empty subexpressions */
> if (node == NULL)
> return true;
> @@ -361,7 +371,7 @@ foreign_expr_walker(Node *node,
> * can't be sent to remote because it might have incompatible
> * semantics on remote side.
> */
> - if (!is_builtin(fe->funcid))
> + if (!is_builtin(fe->funcid) && !is_in_extension(fe->funcid, fpinfo))
> return false;
...
> /*
> + * Returns true if given operator/function is part of an extension declared in the
> + * server options.
> + */
> +static bool
> +is_in_extension(Oid procnumber, PgFdwRelationInfo *fpinfo)
> +{
> + static int nkeys = 1;
> + ScanKeyData key[nkeys];
> + HeapTuple tup;
> + Relation depRel;
> + SysScanDesc scan;
> + int nresults = 0;
> +
> + /* Always return false if we don't have any declared extensions */
> + if ( ! fpinfo->extensions )
> + return false;
> +
> + /* We need this relation to scan */
> + depRel = heap_open(DependRelationId, RowExclusiveLock);
> +
> + /* Scan the system dependency table for a all entries this operator */
> + /* depends on, then iterate through and see if one of them */
> + /* is a registered extension */
> + ScanKeyInit(&key[0],
> + Anum_pg_depend_objid,
> + BTEqualStrategyNumber, F_OIDEQ,
> + ObjectIdGetDatum(procnumber));
> +
> + scan = systable_beginscan(depRel, DependDependerIndexId, true,
> + GetCatalogSnapshot(depRel->rd_id), nkeys, key);
> +
> + while (HeapTupleIsValid(tup = systable_getnext(scan)))
> + {
> + Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
> +
> + if ( foundDep->deptype == DEPENDENCY_EXTENSION )
> + {
> + List *extlist = fpinfo->extensions;
> + ListCell *ext;
> +
> + foreach(ext, extlist)
> + {
> + Oid extension_oid = (Oid) lfirst(ext);
> + if ( foundDep->refobjid == extension_oid )
> + {
> + nresults++;
> + }
> + }
> + }
> + if ( nresults > 0 ) break;
> + }
> +
> + systable_endscan(scan);
> + relation_close(depRel, RowExclusiveLock);
> +
> + return nresults > 0;
> +}
Phew. That's mighty expensive to do at frequency.
I guess it'll be more practical to expand this list once and then do a
binary search on the result for the individual functions
Greetings,
Andres Freund
From | Date | Subject | |
---|---|---|---|
Next Message | Bjorn Munch | 2015-07-21 14:45:21 | Re: Solaris testers wanted for strxfrm() behavior |
Previous Message | Fabien COELHO | 2015-07-21 14:42:52 | Re: pgbench stats per script & other stuff |