Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 59d6140

Browse files
committed
Move ltree parentsel() selectivity function into /contrib/ltree.
1 parent cae5671 commit 59d6140

File tree

8 files changed

+230
-221
lines changed

8 files changed

+230
-221
lines changed

contrib/ltree/expected/ltree.out

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
psql:ltree.sql:7: NOTICE: type "ltree" is not yet defined
33
DETAIL: Creating a shell type definition.
44
psql:ltree.sql:12: NOTICE: argument type ltree is only a shell
5-
psql:ltree.sql:299: NOTICE: type "lquery" is not yet defined
5+
psql:ltree.sql:304: NOTICE: type "lquery" is not yet defined
66
DETAIL: Creating a shell type definition.
7-
psql:ltree.sql:304: NOTICE: argument type lquery is only a shell
8-
psql:ltree.sql:410: NOTICE: type "ltxtquery" is not yet defined
7+
psql:ltree.sql:309: NOTICE: argument type lquery is only a shell
8+
psql:ltree.sql:415: NOTICE: type "ltxtquery" is not yet defined
99
DETAIL: Creating a shell type definition.
10-
psql:ltree.sql:415: NOTICE: argument type ltxtquery is only a shell
11-
psql:ltree.sql:477: NOTICE: type "ltree_gist" is not yet defined
10+
psql:ltree.sql:420: NOTICE: argument type ltxtquery is only a shell
11+
psql:ltree.sql:482: NOTICE: type "ltree_gist" is not yet defined
1212
DETAIL: Creating a shell type definition.
13-
psql:ltree.sql:482: NOTICE: argument type ltree_gist is only a shell
13+
psql:ltree.sql:487: NOTICE: argument type ltree_gist is only a shell
1414
SELECT ''::ltree;
1515
ltree
1616
-------

contrib/ltree/ltree.sql.in

+5
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ RETURNS ltree
225225
AS 'MODULE_PATHNAME'
226226
LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
227227

228+
CREATE FUNCTION ltreeparentsel(internal, oid, internal, integer)
229+
RETURNS float8
230+
AS 'MODULE_PATHNAME'
231+
LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
232+
228233
CREATE OPERATOR @> (
229234
LEFTARG = ltree,
230235
RIGHTARG = ltree,

contrib/ltree/ltree_op.c

+187-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
/*
22
* op function for ltree
33
* Teodor Sigaev <teodor@stack.net>
4-
* $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.9 2006/03/11 04:38:29 momjian Exp $
4+
* $PostgreSQL: pgsql/contrib/ltree/ltree_op.c,v 1.10 2006/04/26 22:32:36 momjian Exp $
55
*/
66

77
#include "ltree.h"
88
#include <ctype.h>
99

10+
#include "access/heapam.h"
11+
#include "catalog/pg_statistic.h"
12+
#include "nodes/relation.h"
13+
#include "utils/lsyscache.h"
14+
#include "utils/selfuncs.h"
15+
#include "utils/syscache.h"
16+
1017
/* compare functions */
1118
PG_FUNCTION_INFO_V1(ltree_cmp);
1219
PG_FUNCTION_INFO_V1(ltree_lt);
@@ -44,6 +51,7 @@ Datum ltree_textadd(PG_FUNCTION_ARGS);
4451
Datum lca(PG_FUNCTION_ARGS);
4552
Datum ltree2text(PG_FUNCTION_ARGS);
4653
Datum text2ltree(PG_FUNCTION_ARGS);
54+
Datum ltreeparentsel(PG_FUNCTION_ARGS);
4755

4856
int
4957
ltree_compare(const ltree * a, const ltree * b)
@@ -551,3 +559,181 @@ ltree2text(PG_FUNCTION_ARGS)
551559

552560
PG_RETURN_POINTER(out);
553561
}
562+
563+
564+
#define DEFAULT_PARENT_SEL 0.001
565+
566+
/*
567+
* ltreeparentsel - Selectivity of parent relationship for ltree data types.
568+
*/
569+
Datum
570+
ltreeparentsel(PG_FUNCTION_ARGS)
571+
{
572+
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
573+
Oid operator = PG_GETARG_OID(1);
574+
List *args = (List *) PG_GETARG_POINTER(2);
575+
int varRelid = PG_GETARG_INT32(3);
576+
VariableStatData vardata;
577+
Node *other;
578+
bool varonleft;
579+
Datum *values;
580+
int nvalues;
581+
float4 *numbers;
582+
int nnumbers;
583+
double selec = 0.0;
584+
585+
/*
586+
* If expression is not variable <@ something or something <@ variable,
587+
* then punt and return a default estimate.
588+
*/
589+
if (!get_restriction_variable(root, args, varRelid,
590+
&vardata, &other, &varonleft))
591+
PG_RETURN_FLOAT8(DEFAULT_PARENT_SEL);
592+
593+
/*
594+
* If the something is a NULL constant, assume operator is strict and
595+
* return zero, ie, operator will never return TRUE.
596+
*/
597+
if (IsA(other, Const) &&
598+
((Const *) other)->constisnull)
599+
{
600+
ReleaseVariableStats(vardata);
601+
PG_RETURN_FLOAT8(0.0);
602+
}
603+
604+
if (HeapTupleIsValid(vardata.statsTuple))
605+
{
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;
729+
}
730+
else
731+
selec = DEFAULT_PARENT_SEL;
732+
733+
ReleaseVariableStats(vardata);
734+
735+
/* result should be in range, but make sure... */
736+
CLAMP_PROBABILITY(selec);
737+
738+
PG_RETURN_FLOAT8((float8) selec);
739+
}

src/backend/utils/adt/geo_selfuncs.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.28 2006/04/26 18:28:29 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.29 2006/04/26 22:32:52 momjian Exp $
1313
*
1414
* XXX These are totally bogus. Perhaps someone will make them do
1515
* something reasonable, someday.
@@ -20,6 +20,7 @@
2020

2121
#include "utils/geo_decls.h"
2222

23+
2324
/*
2425
* Selectivity functions for geometric operators. These are bogus -- unless
2526
* we know the actual key distribution in the index, we can't make a good
@@ -92,4 +93,3 @@ contjoinsel(PG_FUNCTION_ARGS)
9293
{
9394
PG_RETURN_FLOAT8(0.001);
9495
}
95-

0 commit comments

Comments
 (0)