aboutsummaryrefslogtreecommitdiff
path: root/src/backend/statistics/mcv.c
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2019-07-13 00:12:16 +0200
committerTomas Vondra <tomas.vondra@postgresql.org>2019-07-18 11:29:38 +0200
commite8b6ae2130e3a95bb776708a9a7c9cb21fe8ac87 (patch)
treea4da53b2d8031d5d667f443a9ee294cab28e8129 /src/backend/statistics/mcv.c
parenta4303a078c661ebafe8c8c2167b2ad9bf16b32ce (diff)
downloadpostgresql-e8b6ae2130e3a95bb776708a9a7c9cb21fe8ac87.tar.gz
postgresql-e8b6ae2130e3a95bb776708a9a7c9cb21fe8ac87.zip
Fix handling of opclauses in extended statistics
We expect opclauses to have exactly one Var and one Const, but the code was checking the Const by calling is_pseudo_constant_clause() which is incorrect - we need a proper constant. Fixed by using plain IsA(x,Const) to check type of the node. We need to do these checks in two places, so move it into a separate function that can be called in both places. Reported by Andreas Seltenreich, based on crash reported by sqlsmith. Backpatch to v12, where this code was introduced. Discussion: https://postgr.es/m/8736jdhbhc.fsf%40ansel.ydns.eu Backpatch-to: 12
Diffstat (limited to 'src/backend/statistics/mcv.c')
-rw-r--r--src/backend/statistics/mcv.c27
1 files changed, 7 insertions, 20 deletions
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index e62421dfa88..a708a8f6740 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -1561,36 +1561,23 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
if (is_opclause(clause))
{
OpExpr *expr = (OpExpr *) clause;
- bool varonleft = true;
- bool ok;
FmgrInfo opproc;
/* get procedure computing operator selectivity */
RegProcedure oprrest = get_oprrest(expr->opno);
- fmgr_info(get_opcode(expr->opno), &opproc);
+ /* valid only after examine_opclause_expression returns true */
+ Var *var;
+ Const *cst;
+ bool isgt;
- ok = (NumRelids(clause) == 1) &&
- (is_pseudo_constant_clause(lsecond(expr->args)) ||
- (varonleft = false,
- is_pseudo_constant_clause(linitial(expr->args))));
+ fmgr_info(get_opcode(expr->opno), &opproc);
- if (ok)
+ /* extract the var and const from the expression */
+ if (examine_opclause_expression(expr, &var, &cst, &isgt))
{
- Var *var;
- Const *cst;
- bool isgt;
int idx;
- /* extract the var and const from the expression */
- var = (varonleft) ? linitial(expr->args) : lsecond(expr->args);
- cst = (varonleft) ? lsecond(expr->args) : linitial(expr->args);
- isgt = (!varonleft);
-
- /* strip binary-compatible relabeling */
- if (IsA(var, RelabelType))
- var = (Var *) ((RelabelType *) var)->arg;
-
/* match the attribute to a dimension of the statistic */
idx = bms_member_index(keys, var->varattno);