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

Lines changed: 6 additions & 6 deletions
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 187 additions & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy