diff --git a/contrib/ltree/ltree_op.c b/contrib/ltree/ltree_op.c index 6b894861dd4dadcd17916c687f87f14e33749d29..4a49e35ce86841c7220f47560702f8c97a8d914d 100644 --- a/contrib/ltree/ltree_op.c +++ b/contrib/ltree/ltree_op.c @@ -1,19 +1,18 @@ /* * op function for ltree * 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 <ctype.h> -#include "access/heapam.h" -#include "catalog/pg_statistic.h" -#include "nodes/relation.h" #include "utils/lsyscache.h" #include "utils/selfuncs.h" #include "utils/syscache.h" + /* compare functions */ PG_FUNCTION_INFO_V1(ltree_cmp); PG_FUNCTION_INFO_V1(ltree_lt); @@ -34,6 +33,8 @@ PG_FUNCTION_INFO_V1(ltree_textadd); PG_FUNCTION_INFO_V1(lca); PG_FUNCTION_INFO_V1(ltree2text); PG_FUNCTION_INFO_V1(text2ltree); +PG_FUNCTION_INFO_V1(ltreeparentsel); + Datum ltree_cmp(PG_FUNCTION_ARGS); Datum ltree_lt(PG_FUNCTION_ARGS); Datum ltree_le(PG_FUNCTION_ARGS); @@ -576,11 +577,7 @@ ltreeparentsel(PG_FUNCTION_ARGS) VariableStatData vardata; Node *other; bool varonleft; - Datum *values; - int nvalues; - float4 *numbers; - int nnumbers; - double selec = 0.0; + double selec; /* * If expression is not variable <@ something or something <@ variable, @@ -601,131 +598,27 @@ ltreeparentsel(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(0.0); } - if (HeapTupleIsValid(vardata.statsTuple)) + if (IsA(other, Const)) { - Form_pg_statistic stats; - double mcvsum = 0.0; - double mcvsel = 0.0; - double hissel = 0.0; - - stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple); - - if (IsA(other, Const)) - { - /* Variable is being compared to a known non-null constant */ - Datum constval = ((Const *) other)->constvalue; - bool match = false; - int i; - - /* - * Is the constant "<@" to any of the column's most common values? - */ - if (get_attstatsslot(vardata.statsTuple, - vardata.atttype, vardata.atttypmod, - 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; + /* Variable is being compared to a known non-null constant */ + Datum constval = ((Const *) other)->constvalue; + FmgrInfo contproc; + double mcvsum; + double mcvsel; + + fmgr_info(get_opcode(operator), &contproc); + + /* + * Is the constant "<@" to any of the column's most common values? + */ + mcvsel = mcv_selectivity(&vardata, &contproc, constval, varonleft, + &mcvsum); + + /* + * We have the exact selectivity for values appearing in the MCV list; + * use the default selectivity for the rest of the population. + */ + selec = mcvsel + DEFAULT_PARENT_SEL * (1.0 - mcvsum); } else selec = DEFAULT_PARENT_SEL;