2ndQuadrant/pg_stat_plans — pull request #1 by bpineau (2012-11-05 15:15:00+00:00)
Title: Don't segfault on "RESET ALL" queries.

Per parsenodes.h, "RESET ALL" is a VariableSetStmt; yet it doesn't
take a variable name as argument (as op. to other VariableSetKind like
"SET"). Therefore the VariableSetStmt node struct we get from the
parser for a "RESET ALL" query doesn't have a defined "name" member.

But our pgsp_ProcessUtility() hook tries to read the parsetree's struct
"name" member for every VariableSetStmt, causing a backend segfault on
"RESET ALL" queries.

A "RESET ALL" statement will also re-initialise the search_path: we
should update our local search_path copy when we see this statement.

We could just check whether "v->kind == VAR_RESET_ALL", but testing if
v->name is null is more robust/future proof in case other variableless
VariableSetKind statements are added to PostgreSQL later (I believe this
deserves that kind of caution since the outcome would be a segfault).

(gdb) bt
#0 __strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp.S:129
#1 0x00007f9fbf5aba77 in pgsp_ProcessUtility (parsetree=0x24ee858, queryString=0x24edea0 "RESET ALL;", params=0x0, isTopLevel=1 '\001', dest=0x24eeb98,
completionTag=0x7fff49c10710 "") at pg_stat_plans.c:911
#2 0x00000000007134e2 in ProcessUtility (parsetree=0x24ee858, queryString=0x24edea0 "RESET ALL;", params=0x0, isTopLevel=1 '\001', dest=0x24eeb98, completionTag=0x7fff49c10710 ""
at utility.c:332
(gdb) frame 1
(gdb) list
906
907 if (IsA(parsetree, VariableSetStmt))
908 {
909 VariableSetStmt *v = (VariableSetStmt *) parsetree;
910
911 if (strcmp(v->name, "search_path") == 0)
912 {
913 /* search_path changed - update current search_path for backend. */
914 search_path_xor = get_search_path_xor();
915 }
(gdb) print *((VariableSetStmt *) parsetree)
$16 = {type = T_VariableSetStmt, kind = VAR_RESET_ALL, name = 0x0, args = 0x0, is_local = 0 '\000'}