Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0f43083

Browse files
committed
functions.c: copy trees from source_list before parse analysis etc.
This is yet another bit of fallout from the fact that backend/parser(like other code) feels free to scribble on the parse tree it'shanded. In this case that resulted in modifying therelatively-short-lived copy in the cached function's source_list.That would be fine since we only need each source_list tree once... except that if the parser fails after making some changes,the function cache entry remains as-is and will still be thereif the user tries to execute the function again. Then we haveproblems because we're feeding a non-pristine tree to the parser.The most expedient fix is a quick copyObject(). I consideredother answers like somehow marking the cache entry invalidtemporarily, but that would add complexity and I'm not sureit's worth it. In typical scenarios we'd only do this onceper function query per session.Reported-by: Alexander Lakhin <exclusion@gmail.com>Author: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/6d442183-102c-498a-81d1-eeeb086cdc5a@gmail.com
1 parent2ef5790 commit0f43083

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

‎src/backend/executor/functions.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,13 +871,19 @@ prepare_next_query(SQLFunctionHashEntry *func)
871871

872872
/*
873873
* Parse and/or rewrite the query, creating a CachedPlanSource that holds
874-
* a copy of the original parsetree.
874+
* a copy of the original parsetree. Note fine point: we make a copy of
875+
* each original parsetree to ensure that the source_list in pcontext
876+
* remains unmodified during parse analysis and rewrite. This is normally
877+
* unnecessary, but we have to do it in case an error is raised during
878+
* parse analysis. Otherwise, a fresh attempt to execute the function
879+
* will arrive back here and try to work from a corrupted source_list.
875880
*/
876881
if (!func->raw_source)
877882
{
878883
/* Source queries are already parse-analyzed */
879884
Query*parsetree=list_nth_node(Query,func->source_list,qindex);
880885

886+
parsetree=copyObject(parsetree);
881887
plansource=CreateCachedPlanForQuery(parsetree,
882888
func->src,
883889
CreateCommandTag((Node*)parsetree));
@@ -889,6 +895,7 @@ prepare_next_query(SQLFunctionHashEntry *func)
889895
/* Source queries are raw parsetrees */
890896
RawStmt*parsetree=list_nth_node(RawStmt,func->source_list,qindex);
891897

898+
parsetree=copyObject(parsetree);
892899
plansource=CreateCachedPlan(parsetree,
893900
func->src,
894901
CreateCommandTag(parsetree->stmt));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp