From d3f9b11e8bcf5983eeccfb18b1df43def270440a Mon Sep 17 00:00:00 2001 From: Bykov Ivan Date: Fri, 22 Nov 2024 17:35:10 +0500 Subject: [PATCH] Query ID Calculation Fix for DISTINCT / ORDER BY and LIMIT / OFFSET In some cases, we may encounter different query trees with the same IDs. For two structurally similar query subnodes, the query trees may look like this: QueryA->subNodeOne = Value X; QueryA->subNodeTwo = NULL; QueryB->subNodeOne = NULL; QueryB->subNodeTwo = Value X; When the query jumble walker calculates the query ID, it traverses the Query members from top to bottom and generates the same IDs for these two queries because it does not change the hash value when visiting an empty node (= NULL). There are two pairs of subnodes that can trigger this error: - distinctClause and sortClause (both contain a list of SortGroupClauses); - limitOffset and limitCount (both contain an int8 expression). To fix this problem, for every empty node in the Query tree, a '0' character is added to the jumble buffer, which is used for ID calculation. --- src/backend/nodes/queryjumblefuncs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backend/nodes/queryjumblefuncs.c b/src/backend/nodes/queryjumblefuncs.c index 129fb44709..225a49ebc3 100644 --- a/src/backend/nodes/queryjumblefuncs.c +++ b/src/backend/nodes/queryjumblefuncs.c @@ -238,7 +238,12 @@ _jumbleNode(JumbleState *jstate, Node *node) Node *expr = node; if (expr == NULL) + { + const unsigned char null_symbol = '\0'; + + AppendJumble(jstate, &null_symbol, sizeof(unsigned char)); return; + } /* Guard against stack overflow due to overly complex expressions */ check_stack_depth(); -- 2.39.2