>> Yeah. I'm still not exactly convinced that custom-scan will ever allow >> independent development of new plan types (which, with all due respect to >> Robert, is what it was being sold as last year in Ottawa). But I'm not >> opposed in principle to committing it, if we can find a way to have a cleaner >> API for things like setrefs.c. It seems like late-stage planner processing >> in general is an issue for this patch (createplan.c and subselect.c are >> also looking messy). EXPLAIN isn't too great either. >> >> I'm not sure exactly what to do about those cases, but I wonder whether >> things would get better if we had the equivalent of >> expression_tree_walker/mutator capability for plan nodes. The state of >> affairs in setrefs and subselect, at least, is a bit reminiscent of the >> bad old days when we had lots of different bespoke code for traversing >> expression trees. >> > Hmm. If we have something like expression_tree_walker/mutator for plan nodes, > we can pass a walker/mutator function's pointer instead of exposing static > functions that takes recursive jobs. > If custom-plan provider (that has sub-plans) got a callback with walker/ > mutator pointer, all it has to do for sub-plans are calling this new > plan-tree walking support routine with supplied walker/mutator. > It seems to me more simple design than what I did. > I tried to code the similar walker/mutator functions on plan-node tree, however, it was not available to implement these routines enough simple, because the job of walker/mutator functions are not uniform thus caller side also must have a large switch-case branches.
I picked up setrefs.c for my investigation. The set_plan_refs() applies fix_scan_list() on the expression tree being appeared in the plan node if it is delivered from Scan, however, it also applies set_join_references() for subclass of Join, or set_dummy_tlist_references() for some other plan nodes. It implies that the walker/mutator functions of Plan node has to apply different operation according to the type of Plan node. I'm not certain how much different forms are needed. (In addition, set_plan_refs() performs usually like a walker, but often performs as a mutator if trivial subquery....) I'm expecting the function like below. It allows to call plan_walker function for each plan-node and also allows to call expr_walker function for each expression-node on the plan node. bool plan_tree_walker(Plan *plan, bool (*plan_walker) (), bool (*expr_walker) (), void *context) I'd like to see if something other form to implement this routine. One alternative idea to give custom-plan provider a chance to handle its subplans is, to give function pointers (1) to handle recursion of plan-tree and (2) to set up backend's internal state. In case of setrefs.c, set_plan_refs() and fix_expr_common() are minimum necessity for extensions. It also kills necessity to export static functions. How about your thought? -- KaiGai Kohei <kai...@kaigai.gr.jp> -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers