11/*
22 * op function for ltree
33 * Teodor Sigaev <teodor@stack.net>
4- * $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.10 2006/04/26 22:32:36 momjian Exp $
4+ * $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.11 2006/04/27 18:24:35 tgl Exp $
55 */
66
77#include "ltree.h"
8+
89#include <ctype.h>
910
10- #include "access/heapam.h"
11- #include "catalog/pg_statistic.h"
12- #include "nodes/relation.h"
1311#include "utils/lsyscache.h"
1412#include "utils/selfuncs.h"
1513#include "utils/syscache.h"
1614
15+
1716/* compare functions */
1817PG_FUNCTION_INFO_V1 (ltree_cmp );
1918PG_FUNCTION_INFO_V1 (ltree_lt );
@@ -34,6 +33,8 @@ PG_FUNCTION_INFO_V1(ltree_textadd);
3433PG_FUNCTION_INFO_V1 (lca );
3534PG_FUNCTION_INFO_V1 (ltree2text );
3635PG_FUNCTION_INFO_V1 (text2ltree );
36+ PG_FUNCTION_INFO_V1 (ltreeparentsel );
37+
3738Datum ltree_cmp (PG_FUNCTION_ARGS );
3839Datum ltree_lt (PG_FUNCTION_ARGS );
3940Datum ltree_le (PG_FUNCTION_ARGS );
@@ -576,11 +577,7 @@ ltreeparentsel(PG_FUNCTION_ARGS)
576577VariableStatData vardata ;
577578Node * other ;
578579bool varonleft ;
579- Datum * values ;
580- int nvalues ;
581- float4 * numbers ;
582- int nnumbers ;
583- double selec = 0.0 ;
580+ double selec ;
584581
585582/*
586583 * If expression is not variable <@ something or something <@ variable,
@@ -601,131 +598,27 @@ ltreeparentsel(PG_FUNCTION_ARGS)
601598PG_RETURN_FLOAT8 (0.0 );
602599}
603600
604- if (HeapTupleIsValid ( vardata . statsTuple ))
601+ if (IsA ( other , Const ))
605602{
606- Form_pg_statistic stats ;
607- double mcvsum = 0.0 ;
608- double mcvsel = 0.0 ;
609- double hissel = 0.0 ;
610-
611- stats = (Form_pg_statistic )GETSTRUCT (vardata .statsTuple );
612-
613- if (IsA (other ,Const ))
614- {
615- /* Variable is being compared to a known non-null constant */
616- Datum constval = ((Const * )other )-> constvalue ;
617- bool match = false;
618- int i ;
619-
620- /*
621- * Is the constant "<@" to any of the column's most common values?
622- */
623- if (get_attstatsslot (vardata .statsTuple ,
624- vardata .atttype ,vardata .atttypmod ,
625- STATISTIC_KIND_MCV ,InvalidOid ,
626- & values ,& nvalues ,
627- & numbers ,& nnumbers ))
628- {
629- FmgrInfo contproc ;
630-
631- fmgr_info (get_opcode (operator ),& contproc );
632-
633- for (i = 0 ;i < nvalues ;i ++ )
634- {
635- /* be careful to apply operator right way 'round */
636- if (varonleft )
637- match = DatumGetBool (FunctionCall2 (& contproc ,
638- values [i ],
639- constval ));
640- else
641- match = DatumGetBool (FunctionCall2 (& contproc ,
642- constval ,
643- values [i ]));
644-
645- /* calculate total selectivity of all most-common-values */
646- mcvsum += numbers [i ];
647-
648- /* calculate selectivity of matching most-common-values */
649- if (match )
650- mcvsel += numbers [i ];
651- }
652- }
653- else
654- {
655- /* no most-common-values info available */
656- values = NULL ;
657- numbers = NULL ;
658- i = nvalues = nnumbers = 0 ;
659- }
660-
661- free_attstatsslot (vardata .atttype ,values ,nvalues ,NULL ,0 );
662-
663- /*
664- * Is the constant "<@" to any of the column's histogram values?
665- */
666- if (get_attstatsslot (vardata .statsTuple ,
667- vardata .atttype ,vardata .atttypmod ,
668- STATISTIC_KIND_HISTOGRAM ,InvalidOid ,
669- & values ,& nvalues ,
670- NULL ,NULL ))
671- {
672- FmgrInfo contproc ;
673-
674- fmgr_info (get_opcode (operator ),& contproc );
675-
676- for (i = 0 ;i < nvalues ;i ++ )
677- {
678- /* be careful to apply operator right way 'round */
679- if (varonleft )
680- match = DatumGetBool (FunctionCall2 (& contproc ,
681- values [i ],
682- constval ));
683- else
684- match = DatumGetBool (FunctionCall2 (& contproc ,
685- constval ,
686- values [i ]));
687- /* count matching histogram values */
688- if (match )
689- hissel ++ ;
690- }
691-
692- if (hissel > 0.0 )
693- {
694- /*
695- * some matching values found inside histogram, divide
696- * matching entries number by total histogram entries to
697- * get the histogram related selectivity
698- */
699- hissel /=nvalues ;
700- }
701- }
702- else
703- {
704- /* no histogram info available */
705- values = NULL ;
706- i = nvalues = 0 ;
707- }
708-
709- free_attstatsslot (vardata .atttype ,values ,nvalues ,
710- NULL ,0 );
711-
712-
713- /*
714- * calculate selectivity based on MCV and histogram result
715- * histogram selectivity needs to be scaled down if there are any
716- * most-common-values
717- */
718- selec = mcvsel + hissel * (1.0 - mcvsum );
719-
720- /*
721- * don't return 0.0 selectivity unless all table values are inside
722- * mcv
723- */
724- if (selec == 0.0 && mcvsum != 1.0 )
725- selec = DEFAULT_PARENT_SEL ;
726- }
727- else
728- selec = DEFAULT_PARENT_SEL ;
603+ /* Variable is being compared to a known non-null constant */
604+ Datum constval = ((Const * )other )-> constvalue ;
605+ FmgrInfo contproc ;
606+ double mcvsum ;
607+ double mcvsel ;
608+
609+ fmgr_info (get_opcode (operator ),& contproc );
610+
611+ /*
612+ * Is the constant "<@" to any of the column's most common values?
613+ */
614+ mcvsel = mcv_selectivity (& vardata ,& contproc ,constval ,varonleft ,
615+ & mcvsum );
616+
617+ /*
618+ * We have the exact selectivity for values appearing in the MCV list;
619+ * use the default selectivity for the rest of the population.
620+ */
621+ selec = mcvsel + DEFAULT_PARENT_SEL * (1.0 - mcvsum );
729622}
730623else
731624selec = DEFAULT_PARENT_SEL ;