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


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to