8000 Fix booltestsel() for case where we have NULL stats but not MCV stats. · sqlparser/postgres@8e992b0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8e992b0

Browse files
committed
Fix booltestsel() for case where we have NULL stats but not MCV stats.
In a boolean column that contains mostly nulls, ANALYZE might not find enough non-null values to populate the most-common-values stats, but it would still create a pg_statistic entry with stanullfrac set. The logic in booltestsel() for this situation did the wrong thing for "col IS NOT TRUE" and "col IS NOT FALSE" tests, forgetting that null values would satisfy these tests (so that the true selectivity would be close to one, not close to zero). Per bug #8274. Fix by Andrew Gierth, some comment-smithing by me.
1 parent f6a6d20 commit 8e992b0

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

src/backend/utils/adt/selfuncs.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,31 +1494,29 @@ booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg,
14941494
/*
14951495
* No most-common-value info available. Still have null fraction
14961496
* information, so use it for IS [NOT] UNKNOWN. Otherwise adjust
1497-
* for null fraction and assume an even split for boolean tests.
1497+
* for null fraction and assume a 50-50 split of TRUE and FALSE.
14981498
*/
14991499
switch (booltesttype)
15001500
{
15011501
case IS_UNKNOWN:
1502-
1503-
/*
1504-
* Use freq_null directly.
1505-
*/
1502+
/* select only NULL values */
15061503
selec = freq_null;
15071504
break;
15081505
case IS_NOT_UNKNOWN:
1509-
1510-
/*
1511-
* Select not unknown (not null) values. Calculate from
1512-
* freq_null.
1513-
*/
1506+
/* select non-NULL values */
15141507
selec = 1.0 - freq_null;
15151508
break;
15161509
case IS_TRUE:
1517-
case IS_NOT_TRUE:
15181510
case IS_FALSE:
1519-
case IS_NOT_FALSE:
1511+
/* Assume we select half of the non-NULL values */
15201512
selec = (1.0 - freq_null) / 2.0;
15211513
break;
1514+
case IS_NOT_TRUE:
1515+
case IS_NOT_FALSE:
1516+
/* Assume we select NULLs plus half of the non-NULLs */
1517+
/* equiv. to freq_null + (1.0 - freq_null) / 2.0 */
1518+
selec = (freq_null + 1.0) / 2.0;
1519+
break;
15221520
default:
15231521
elog(ERROR, "unrecognized booltesttype: %d",
15241522
(int) booltesttype);

0 commit comments

Comments
 (0)
0