Commit 4ade4fe4 authored by Tom Lane's avatar Tom Lane

Fix ltreeparentsel so it actually works ...

parent 0f0a3309
/* /*
* op function for ltree * op function for ltree
* Teodor Sigaev <teodor@stack.net> * Teodor Sigaev <teodor@stack.net>
* $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.10 2006/04/26 22:32:36 momjian Exp $ * $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.11 2006/04/27 18:24:35 tgl Exp $
*/ */
#include "ltree.h" #include "ltree.h"
#include <ctype.h> #include <ctype.h>
#include "access/heapam.h"
#include "catalog/pg_statistic.h"
#include "nodes/relation.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/selfuncs.h" #include "utils/selfuncs.h"
#include "utils/syscache.h" #include "utils/syscache.h"
/* compare functions */ /* compare functions */
PG_FUNCTION_INFO_V1(ltree_cmp); PG_FUNCTION_INFO_V1(ltree_cmp);
PG_FUNCTION_INFO_V1(ltree_lt); PG_FUNCTION_INFO_V1(ltree_lt);
...@@ -34,6 +33,8 @@ PG_FUNCTION_INFO_V1(ltree_textadd); ...@@ -34,6 +33,8 @@ PG_FUNCTION_INFO_V1(ltree_textadd);
PG_FUNCTION_INFO_V1(lca); PG_FUNCTION_INFO_V1(lca);
PG_FUNCTION_INFO_V1(ltree2text); PG_FUNCTION_INFO_V1(ltree2text);
PG_FUNCTION_INFO_V1(text2ltree); PG_FUNCTION_INFO_V1(text2ltree);
PG_FUNCTION_INFO_V1(ltreeparentsel);
Datum ltree_cmp(PG_FUNCTION_ARGS); Datum ltree_cmp(PG_FUNCTION_ARGS);
Datum ltree_lt(PG_FUNCTION_ARGS); Datum ltree_lt(PG_FUNCTION_ARGS);
Datum ltree_le(PG_FUNCTION_ARGS); Datum ltree_le(PG_FUNCTION_ARGS);
...@@ -576,11 +577,7 @@ ltreeparentsel(PG_FUNCTION_ARGS) ...@@ -576,11 +577,7 @@ ltreeparentsel(PG_FUNCTION_ARGS)
VariableStatData vardata; VariableStatData vardata;
Node *other; Node *other;
bool varonleft; bool varonleft;
Datum *values; double selec;
int nvalues;
float4 *numbers;
int nnumbers;
double selec = 0.0;
/* /*
* If expression is not variable <@ something or something <@ variable, * If expression is not variable <@ something or something <@ variable,
...@@ -601,131 +598,27 @@ ltreeparentsel(PG_FUNCTION_ARGS) ...@@ -601,131 +598,27 @@ ltreeparentsel(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(0.0); PG_RETURN_FLOAT8(0.0);
} }
if (HeapTupleIsValid(vardata.statsTuple)) if (IsA(other, Const))
{ {
Form_pg_statistic stats; /* Variable is being compared to a known non-null constant */
double mcvsum = 0.0; Datum constval = ((Const *) other)->constvalue;
double mcvsel = 0.0; FmgrInfo contproc;
double hissel = 0.0; double mcvsum;
double mcvsel;
stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
fmgr_info(get_opcode(operator), &contproc);
if (IsA(other, Const))
{ /*
/* Variable is being compared to a known non-null constant */ * Is the constant "<@" to any of the column's most common values?
Datum constval = ((Const *) other)->constvalue; */
bool match = false; mcvsel = mcv_selectivity(&vardata, &contproc, constval, varonleft,
int i; &mcvsum);
/* /*
* Is the constant "<@" to any of the column's most common values? * We have the exact selectivity for values appearing in the MCV list;
*/ * use the default selectivity for the rest of the population.
if (get_attstatsslot(vardata.statsTuple, */
vardata.atttype, vardata.atttypmod, selec = mcvsel + DEFAULT_PARENT_SEL * (1.0 - mcvsum);
STATISTIC_KIND_MCV, InvalidOid,
&values, &nvalues,
&numbers, &nnumbers))
{
FmgrInfo contproc;
fmgr_info(get_opcode(operator), &contproc);
for (i = 0; i < nvalues; i++)
{
/* be careful to apply operator right way 'round */
if (varonleft)
match = DatumGetBool(FunctionCall2(&contproc,
values[i],
constval));
else
match = DatumGetBool(FunctionCall2(&contproc,
constval,
values[i]));
/* calculate total selectivity of all most-common-values */
mcvsum += numbers[i];
/* calculate selectivity of matching most-common-values */
if (match)
mcvsel += numbers[i];
}
}
else
{
/* no most-common-values info available */
values = NULL;
numbers = NULL;
i = nvalues = nnumbers = 0;
}
free_attstatsslot(vardata.atttype, values, nvalues, NULL, 0);
/*
* Is the constant "<@" to any of the column's histogram values?
*/
if (get_attstatsslot(vardata.statsTuple,
vardata.atttype, vardata.atttypmod,
STATISTIC_KIND_HISTOGRAM, InvalidOid,
&values, &nvalues,
NULL, NULL))
{
FmgrInfo contproc;
fmgr_info(get_opcode(operator), &contproc);
for (i = 0; i < nvalues; i++)
{
/* be careful to apply operator right way 'round */
if (varonleft)
match = DatumGetBool(FunctionCall2(&contproc,
values[i],
constval));
else
match = DatumGetBool(FunctionCall2(&contproc,
constval,
values[i]));
/* count matching histogram values */
if (match)
hissel++;
}
if (hissel > 0.0)
{
/*
* some matching values found inside histogram, divide
* matching entries number by total histogram entries to
* get the histogram related selectivity
*/
hissel /= nvalues;
}
}
else
{
/* no histogram info available */
values = NULL;
i = nvalues = 0;
}
free_attstatsslot(vardata.atttype, values, nvalues,
NULL, 0);
/*
* calculate selectivity based on MCV and histogram result
* histogram selectivity needs to be scaled down if there are any
* most-common-values
*/
selec = mcvsel + hissel * (1.0 - mcvsum);
/*
* don't return 0.0 selectivity unless all table values are inside
* mcv
*/
if (selec == 0.0 && mcvsum != 1.0)
selec = DEFAULT_PARENT_SEL;
}
else
selec = DEFAULT_PARENT_SEL;
} }
else else
selec = DEFAULT_PARENT_SEL; selec = DEFAULT_PARENT_SEL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment