Delaying the planning of unnamed statements until Bind
От | Oliver Jowett |
---|---|
Тема | Delaying the planning of unnamed statements until Bind |
Дата | |
Msg-id | 40AC1F4A.4000904@opencloud.com обсуждение исходный текст |
Ответы |
Re: Delaying the planning of unnamed statements until Bind
|
Список | pgsql-hackers |
Hello pgsql-hackers, Following a recent discussion on the JDBC list (http://archives.postgresql.org/pgsql-jdbc/2004-05/msg00100.php) I'm looking at modifying when unnamed statements received via a v3 protocol Parse message are planned. The idea is to delay planning until the Bind message arrives, so that the planner benefits from knowing the actual parameter values in use. This means that clients such as JDBC can use an unnamed Parse/Bind as a way to provide typed and/or binary parameter values without running the risk of worsening the query plan. As this is my first excursion into the backend code (and the first time I've touched any C for about a year, for that matter) I'd like to get a sanity check on what I'm doing.. So far my changes involve: 1. Add a ParamListInfo parameter to pg_plan_query(), pg_plan_queries(), planner(); this provides actual parameter values or NULL if unavailiable. All existing callers except execute_bind_message pass NULL. 2. In execute_parse_message, if parsing into the unnamed statement, first parse the query. If there are any parameters present, don't plan the query yet (set unnamed_stat_pstmt->plan_list = NULL). Otherwise, parse and plan as normal. 3. In execute_bind_message, if the source statement is not planned (plan_list == NULL), plan it, passing the concrete parameter values received in the Bind message. The planning happens using the target portal's memory context; the resulting plan_list is only used for this portal and the source statement remains unplanned. Move the call to PortalDefineQuery() so that it occurs after parameters have been received and any planning has been done. 4. In planner(), if parameters are provided, replace Param nodes with Const nodes in the query tree where appropriate. For 4) I have a couple of options: a) thread a ParamListInfo parameter through the planner code. Pass it to eval_const_expressions(). Make eval_const_expressions() do the Param->Const replacement where possible in the mutated tree it produces. b) if parameters are provided, do the Param->Const replacement at the start of planner() using a custom tree walker. 4a) appears more efficient as it doesn't need another intermediate tree copy, but it requires threading the parameter values through many planner functions. There are quite a few (20-30ish?) functions affected. 4b) appears simpler to implement but requires more tree copying at runtime. ... Does this look like a reasonable approach to take? Any suggestions, or gotchas I've missed? -O
В списке pgsql-hackers по дате отправления: