]> granicus.if.org Git - postgresql/commitdiff
Check for interrupts and stack overflow during rule/view dumps.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 30 Apr 2014 17:46:22 +0000 (13:46 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 30 Apr 2014 17:46:22 +0000 (13:46 -0400)
Since ruleutils.c recurses, it could be driven to stack overflow by
deeply nested constructs.  Very large queries might also take long
enough to deparse that a check for interrupts seems like a good idea.
Stick appropriate tests into a couple of key places.

Noted by Greg Stark.  Back-patch to all supported branches.

src/backend/utils/adt/ruleutils.c

index d4bff6a6c88ce6ab90813fe1e01ed2fc1ee1e208..8bf5a791375b16dd54eb5b4dba1ebf690e3b31e2 100644 (file)
@@ -36,6 +36,7 @@
 #include "commands/tablespace.h"
 #include "executor/spi.h"
 #include "funcapi.h"
+#include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
@@ -2608,6 +2609,10 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace,
        deparse_context context;
        deparse_namespace dpns;
 
+       /* Guard against excessively long or deeply-nested queries */
+       CHECK_FOR_INTERRUPTS();
+       check_stack_depth();
+
        /*
         * Before we begin to examine the query, acquire locks on referenced
         * relations, and fix up deleted columns in JOIN RTEs.  This ensures
@@ -3057,6 +3062,10 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context,
        StringInfo      buf = context->buf;
        bool            need_paren;
 
+       /* Guard against excessively long or deeply-nested queries */
+       CHECK_FOR_INTERRUPTS();
+       check_stack_depth();
+
        if (IsA(setOp, RangeTblRef))
        {
                RangeTblRef *rtr = (RangeTblRef *) setOp;
@@ -4842,6 +4851,10 @@ get_rule_expr(Node *node, deparse_context *context,
        if (node == NULL)
                return;
 
+       /* Guard against excessively long or deeply-nested queries */
+       CHECK_FOR_INTERRUPTS();
+       check_stack_depth();
+
        /*
         * Each level of get_rule_expr must emit an indivisible term
         * (parenthesized if necessary) to ensure result is reparsed into the same