public inbox for [email protected]  
help / color / mirror / Atom feed
From: SATYANARAYANA NARLAPURAM <[email protected]>
To: PostgreSQL Hackers <[email protected]>
To: Ashutosh Bapat <[email protected]>
To: Peter Eisentraut <[email protected]>
Subject: Bug: Missing check_stack_depth() in GRAPH_TABLE rewriter
Date: Fri, 10 Apr 2026 20:57:50 -0700
Message-ID: <CAHg+QDfgK0xddH8f3eAb+UVn7sBDOnv8RvM6OkP4HtHAt6aD7w@mail.gmail.com> (raw)

Hi Hackers,

Two recursive functions, generate_setop_from_pathqueries() and
generate_queries_for_path_pattern_recurse() in GRAPH_TABLE rewriter are
missing check_stack_depth() calls. Consider a property graph with  400 edge
tables with a 2-hop pattern produce 160,000 path queries and therefore
160,000 recursion frames in
generate_setop_from_pathqueries(). This can easily exceed the OS stack
limit for some systems and crashes the backend.

I am proposing a stop gap fix of checking stack depth by calling
check_stack_depth for now but in future we may want to reduce the recursion
depth (for example use a balanced tree to reduce depth from O(N) to O(log
N).

Attached a patch for adding the check_stack_depth() check.

Repro:

CREATE TABLE sv (id int PRIMARY KEY);
  INSERT INTO sv VALUES (1);

  DO $$
  BEGIN
    FOR i IN 1..400 LOOP
      EXECUTE format(
        'CREATE TABLE se_%s (id int PRIMARY KEY, src int, dst int)', i);
    END LOOP;
  END$$;

  DO $$
  DECLARE
    sql text;
    edges text := '';
  BEGIN
    FOR i IN 1..400 LOOP
      IF i > 1 THEN edges := edges || ', '; END IF;
      edges := edges || format(
        'se_%s KEY (id) SOURCE KEY (src) REFERENCES sv (id) '
        'DESTINATION KEY (dst) REFERENCES sv (id)', i);
    END LOOP;
    EXECUTE 'CREATE PROPERTY GRAPH g VERTEX TABLES (sv KEY (id)) '
         || 'EDGE TABLES (' || edges || ')';
  END$$;

  SELECT * FROM GRAPH_TABLE(g
    MATCH (a)-[e1]->(b)-[e2]->(c)
    COLUMNS(a.id AS a_id))
  LIMIT 1;

Thanks,
Satya


Attachments:

  [application/octet-stream] 0001-graph-table-check-stack-depth.patch (1.9K, 3-0001-graph-table-check-stack-depth.patch)
  download | inline diff:
From 7920501aea7877bcda762bf0cdd14b20b817eadb Mon Sep 17 00:00:00 2001
From: Satya Narlapuram <[email protected]>
Date: Sat, 11 Apr 2026 03:35:06 +0000
Subject: [PATCH] Add check_stack_depth() to GRAPH_TABLE rewriter recursive
 functions

generate_setop_from_pathqueries() builds a right-recursive UNION ALL tree
with recursion depth equal to the number of valid path queries. Similarly,
generate_queries_for_path_pattern_recurse() recurses once per path factor
position to enumerate path combinations. Neither function called
check_stack_depth().

Add check_stack_depth() to both functions so that excessive recursion is
caught cleanly with an ERROR rather than a server crash.
---
 src/backend/rewrite/rewriteGraphTable.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/backend/rewrite/rewriteGraphTable.c b/src/backend/rewrite/rewriteGraphTable.c
index 2c3199d3..429ef1cf 100644
--- a/src/backend/rewrite/rewriteGraphTable.c
+++ b/src/backend/rewrite/rewriteGraphTable.c
@@ -17,6 +17,7 @@
 #include "access/sysattr.h"
 #include "access/table.h"
 #include "access/htup_details.h"
+#include "miscadmin.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_propgraph_element.h"
 #include "catalog/pg_propgraph_element_label.h"
@@ -361,6 +362,9 @@ generate_queries_for_path_pattern_recurse(RangeTblEntry *rte, List *pathqueries,
 {
 	List	   *path_elems = list_nth_node(List, path_elem_lists, elempos);
 
+	/* Guard against stack overflow due to complex path patterns. */
+	check_stack_depth();
+
 	foreach_ptr(struct path_element, pe, path_elems)
 	{
 		/* Update current path being built with current element. */
@@ -698,6 +702,9 @@ generate_setop_from_pathqueries(List *pathqueries, List **rtable, List **targetl
 	List	   *rtargetlist;
 	ParseNamespaceItem *pni;
 
+	/* Guard against stack overflow due to many path queries. */
+	check_stack_depth();
+
 	/* Recursion termination condition. */
 	if (list_length(pathqueries) == 0)
 	{
-- 
2.43.0



view thread (4+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Bug: Missing check_stack_depth() in GRAPH_TABLE rewriter
  In-Reply-To: <CAHg+QDfgK0xddH8f3eAb+UVn7sBDOnv8RvM6OkP4HtHAt6aD7w@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox