Re: [PATCH] postgres_fdw extension support - Mailing list pgsql-hackers

From Andres Freund
Subject Re: [PATCH] postgres_fdw extension support
Date
Msg-id 20150721144501.GD13636@awork2.anarazel.de
Whole thread Raw
In response to Re: [PATCH] postgres_fdw extension support  (Paul Ramsey <pramsey@cleverelephant.ca>)
Responses Re: [PATCH] postgres_fdw extension support
List 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



pgsql-hackers by date:

Previous
From: Fabien COELHO
Date:
Subject: Re: pgbench stats per script & other stuff
Next
From: Bjorn Munch
Date:
Subject: Re: Solaris testers wanted for strxfrm() behavior