Julius Stroffek <[EMAIL PROTECTED]> writes:
> I understood that if the user creates his own implementation of the 
> planner which can be stored in some external library, he have to provide 
> some C language function as a "hook activator" which will assign the 
> desired value to the planner_hook variable. Both, the activator function 
> and the new planner implementation have to be located in the same 
> dynamic library which will be loaded when CREATE FUNCTION statement 
> would be used on "hook activator" function.

You could do it that way if you wanted, but a minimalistic solution is
just to install the hook from the _PG_init function of a loadable
library, and then LOAD is sufficient for a user to execute the thing.
There's a small example at

Also, having the loadable module add a custom GUC variable would likely
be a preferable solution for control purposes than making specialized
functions.  I attach another small hack I made recently, which simply
scales all the planner's relation size estimates by a scale_factor GUC;
this is handy for investigating how a plan will change with relation
size, without having to actually create gigabytes of test data.

> There are more things in the proposal as a new pg_optimizer catalog and 
> different way of configuring the hooks. However, this thinks are not 
> mandatory for the functionality but are more user friendly.

Granted, but at this point we are talking about infrastructure for
planner-hackers to play with, not something that's intended to be a
long-term API for end users.  It may or may not happen that we ever
need a user API for this at all.  I think a planner that just "does the
right thing" is far preferable to one with a lot of knobs that users
have to know how to twiddle, so I see this more as scaffolding on which
someone can build and test the replacement for GEQO; which ultimately
would go in without any user-visible API additions.

                        regards, tom lane

#include "postgres.h"

#include "fmgr.h"
#include "commands/explain.h"
#include "optimizer/plancat.h"
#include "optimizer/planner.h"
#include "utils/guc.h"


void            _PG_init(void);
void            _PG_fini(void);

static double scale_factor = 1.0;

static void my_get_relation_info(PlannerInfo *root, Oid relationObjectId,
inhparent, RelOptInfo *rel);

 * Get control during planner's get_relation_info() function, which sets up
 * a RelOptInfo struct based on the system catalog contents.  We can modify
 * the struct contents to cause the planner to work with a hypothetical
 * situation rather than what's actually in the catalogs.
 * This simplistic example just scales all relation size estimates by a
 * user-settable factor.
static void
my_get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
                                         RelOptInfo *rel)
        ListCell   *ilist;

        /* Do nothing for an inheritance parent RelOptInfo */
        if (inhparent)

        rel->pages = (BlockNumber) ceil(rel->pages * scale_factor);
        rel->tuples = ceil(rel->tuples * scale_factor);

        foreach(ilist, rel->indexlist)
                IndexOptInfo *ind = (IndexOptInfo *) lfirst(ilist);

                ind->pages = (BlockNumber) ceil(ind->pages * scale_factor);
                ind->tuples = ceil(ind->tuples * scale_factor);

 * _pg_init()                   - library load-time initialization
 * DO NOT make this static nor change its name!
        /* Get into the hooks we need to be in all the time */
        get_relation_info_hook = my_get_relation_info;
        /* Make scale_factor accessible through GUC */

 * _PG_fini()                   - library unload-time finalization
 * DO NOT make this static nor change its name!
        /* Get out of all the hooks (just to be sure) */
        get_relation_info_hook = NULL;
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?


Reply via email to