Skip to content

Commit b81211f

Browse files
Skip queries which don't touch any rows from anonymization.
1 parent f2c7fc7 commit b81211f

File tree

5 files changed

+39
-14
lines changed

5 files changed

+39
-14
lines changed

pg_diffix/query/validation.h

-6
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,4 @@ extern bool is_supported_numeric_type(Oid type);
4545
*/
4646
extern double numeric_value_to_double(Oid type, Datum value);
4747

48-
/*
49-
* If argument is a `cast` expression, returns the casted subject node.
50-
* Otherwise, returns the given argument as is.
51-
*/
52-
extern Node *unwrap_cast(Node *node);
53-
5448
#endif /* PG_DIFFIX_VALIDATION_H */

src/query/anonymization.c

+18-7
Original file line numberDiff line numberDiff line change
@@ -620,17 +620,28 @@ static void compile_anonymizing_query(Query *query, List *personal_relations, An
620620
wrap_having_qual(query);
621621
}
622622

623-
static bool is_anonymizing_query(Query *query, List *personal_relations)
623+
static bool are_qualifiers_always_false(Node *quals)
624624
{
625-
if (query->limitCount != NULL)
625+
if (quals == NULL)
626+
return false;
627+
628+
if (!IsA(quals, Const))
626629
{
627-
Node *limit = unwrap_cast(query->limitCount);
628-
if (IsA(limit, Const) &&
629-
((Const *)limit)->consttype == INT4OID &&
630-
DatumGetInt32(((Const *)limit)->constvalue) == 0)
631-
return false; /* No need for anonymization if no rows are requested. */
630+
quals = eval_const_expressions(NULL, quals);
631+
if (!IsA(quals, Const))
632+
return false;
632633
}
633634

635+
Const *result = (Const *)quals;
636+
Assert(result->consttype == BOOLOID);
637+
return result->constisnull || DatumGetBool(result->constvalue) == false;
638+
}
639+
640+
static bool is_anonymizing_query(Query *query, List *personal_relations)
641+
{
642+
if (are_qualifiers_always_false(query->jointree->quals))
643+
return false; /* No need for anonymization if no rows will be processed. */
644+
634645
ListCell *cell;
635646
foreach (cell, query->rtable)
636647
{

src/query/validation.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ static bool is_datetime_to_string_cast(CoerceViaIO *expr)
138138
return TypeCategory(exprType(arg)) == TYPCATEGORY_DATETIME && TypeCategory(expr->resulttype) == TYPCATEGORY_STRING;
139139
}
140140

141-
Node *unwrap_cast(Node *node)
141+
static Node *unwrap_cast(Node *node)
142142
{
143143
if (IsA(node, FuncExpr))
144144
{

test/expected/misc.out

+15
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,18 @@ EXPLAIN SELECT city FROM test_customers ORDER BY 1;
197197
-> Seq Scan on test_customers
198198
(6 rows)
199199

200+
-- Allow queries that exclude all rows
201+
SELECT FROM test_customers WHERE FALSE;
202+
--
203+
(0 rows)
204+
205+
SELECT TRUE AS "_" FROM test_customers WHERE 1 <> 1 LIMIT 0;
206+
_
207+
---
208+
(0 rows)
209+
210+
SELECT id FROM test_customers WHERE NULL = NULL;
211+
id
212+
----
213+
(0 rows)
214+

test/sql/misc.sql

+5
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,8 @@ EXPLAIN (ANALYZE, SUMMARY false, TIMING false, COSTS true) SELECT name FROM test
9595

9696
-- EXPLAIN prints group/sort names
9797
EXPLAIN SELECT city FROM test_customers ORDER BY 1;
98+
99+
-- Allow queries that exclude all rows
100+
SELECT FROM test_customers WHERE FALSE;
101+
SELECT TRUE AS "_" FROM test_customers WHERE 1 <> 1 LIMIT 0;
102+
SELECT id FROM test_customers WHERE NULL = NULL;

0 commit comments

Comments
 (0)