|
15 | 15 | *
|
16 | 16 | *
|
17 | 17 | * IDENTIFICATION
|
18 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.199 2006/04/20 17:50:18 tgl Exp $ |
| 18 | + * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.200 2006/04/26 18:28:29 momjian Exp $ |
19 | 19 | *
|
20 | 20 | *-------------------------------------------------------------------------
|
21 | 21 | */
|
@@ -4852,3 +4852,182 @@ gistcostestimate(PG_FUNCTION_ARGS)
|
4852 | 4852 |
|
4853 | 4853 | PG_RETURN_VOID();
|
4854 | 4854 | }
|
| 4855 | + |
| 4856 | + |
| 4857 | +#defineDEFAULT_PARENT_SEL 0.001 |
| 4858 | + |
| 4859 | +/* |
| 4860 | + *parentsel - Selectivity of parent relationship for ltree data types. |
| 4861 | + */ |
| 4862 | +Datum |
| 4863 | +parentsel(PG_FUNCTION_ARGS) |
| 4864 | +{ |
| 4865 | +PlannerInfo*root= (PlannerInfo*)PG_GETARG_POINTER(0); |
| 4866 | +Oidoperator=PG_GETARG_OID(1); |
| 4867 | +List*args= (List*)PG_GETARG_POINTER(2); |
| 4868 | +intvarRelid=PG_GETARG_INT32(3); |
| 4869 | +VariableStatDatavardata; |
| 4870 | +Node*other; |
| 4871 | +boolvaronleft; |
| 4872 | +Datum*values; |
| 4873 | +intnvalues; |
| 4874 | +float4*numbers; |
| 4875 | +intnnumbers; |
| 4876 | +doubleselec=0.0; |
| 4877 | + |
| 4878 | +/* |
| 4879 | + * If expression is not variable <@ something or something <@ variable, |
| 4880 | + * then punt and return a default estimate. |
| 4881 | + */ |
| 4882 | +if (!get_restriction_variable(root,args,varRelid, |
| 4883 | +&vardata,&other,&varonleft)) |
| 4884 | +PG_RETURN_FLOAT8(DEFAULT_PARENT_SEL); |
| 4885 | + |
| 4886 | +/* |
| 4887 | + * If the something is a NULL constant, assume operator is strict and |
| 4888 | + * return zero, ie, operator will never return TRUE. |
| 4889 | + */ |
| 4890 | +if (IsA(other,Const)&& |
| 4891 | +((Const*)other)->constisnull) |
| 4892 | +{ |
| 4893 | +ReleaseVariableStats(vardata); |
| 4894 | +PG_RETURN_FLOAT8(0.0); |
| 4895 | +} |
| 4896 | + |
| 4897 | +if (HeapTupleIsValid(vardata.statsTuple)) |
| 4898 | +{ |
| 4899 | +Form_pg_statisticstats; |
| 4900 | +doublemcvsum=0.0; |
| 4901 | +doublemcvsel=0.0; |
| 4902 | +doublehissel=0.0; |
| 4903 | + |
| 4904 | +stats= (Form_pg_statistic)GETSTRUCT(vardata.statsTuple); |
| 4905 | + |
| 4906 | +if (IsA(other,Const)) |
| 4907 | +{ |
| 4908 | +/* Variable is being compared to a known non-null constant */ |
| 4909 | +Datumconstval= ((Const*)other)->constvalue; |
| 4910 | +boolmatch= false; |
| 4911 | +inti; |
| 4912 | + |
| 4913 | +/* |
| 4914 | + * Is the constant "<@" to any of the column's most common values? |
| 4915 | + */ |
| 4916 | +if (get_attstatsslot(vardata.statsTuple, |
| 4917 | +vardata.atttype,vardata.atttypmod, |
| 4918 | +STATISTIC_KIND_MCV,InvalidOid, |
| 4919 | +&values,&nvalues, |
| 4920 | +&numbers,&nnumbers)) |
| 4921 | +{ |
| 4922 | +FmgrInfocontproc; |
| 4923 | + |
| 4924 | +fmgr_info(get_opcode(operator),&contproc); |
| 4925 | + |
| 4926 | +for (i=0;i<nvalues;i++) |
| 4927 | +{ |
| 4928 | +/* be careful to apply operator right way 'round */ |
| 4929 | +if (varonleft) |
| 4930 | +match=DatumGetBool(FunctionCall2(&contproc, |
| 4931 | +values[i], |
| 4932 | +constval)); |
| 4933 | +else |
| 4934 | +match=DatumGetBool(FunctionCall2(&contproc, |
| 4935 | +constval, |
| 4936 | +values[i])); |
| 4937 | + |
| 4938 | +/* calculate total selectivity of all most-common-values */ |
| 4939 | +mcvsum+=numbers[i]; |
| 4940 | + |
| 4941 | +/* calculate selectivity of matching most-common-values */ |
| 4942 | +if (match) |
| 4943 | +mcvsel+=numbers[i]; |
| 4944 | +} |
| 4945 | +} |
| 4946 | +else |
| 4947 | +{ |
| 4948 | +/* no most-common-values info available */ |
| 4949 | +values=NULL; |
| 4950 | +numbers=NULL; |
| 4951 | +i=nvalues=nnumbers=0; |
| 4952 | +} |
| 4953 | + |
| 4954 | +free_attstatsslot(vardata.atttype,values,nvalues,NULL,0); |
| 4955 | + |
| 4956 | +/* |
| 4957 | + * Is the constant "<@" to any of the column's histogram values? |
| 4958 | + */ |
| 4959 | +if (get_attstatsslot(vardata.statsTuple, |
| 4960 | +vardata.atttype,vardata.atttypmod, |
| 4961 | +STATISTIC_KIND_HISTOGRAM,InvalidOid, |
| 4962 | +&values,&nvalues, |
| 4963 | +NULL,NULL)) |
| 4964 | +{ |
| 4965 | +FmgrInfocontproc; |
| 4966 | + |
| 4967 | +fmgr_info(get_opcode(operator),&contproc); |
| 4968 | + |
| 4969 | +for (i=0;i<nvalues;i++) |
| 4970 | +{ |
| 4971 | +/* be careful to apply operator right way 'round */ |
| 4972 | +if (varonleft) |
| 4973 | +match=DatumGetBool(FunctionCall2(&contproc, |
| 4974 | +values[i], |
| 4975 | +constval)); |
| 4976 | +else |
| 4977 | +match=DatumGetBool(FunctionCall2(&contproc, |
| 4978 | +constval, |
| 4979 | +values[i])); |
| 4980 | +/* count matching histogram values */ |
| 4981 | +if (match) |
| 4982 | +hissel++; |
| 4983 | +} |
| 4984 | + |
| 4985 | +if (hissel>0.0) |
| 4986 | +{ |
| 4987 | +/* |
| 4988 | + * some matching values found inside histogram, divide |
| 4989 | + * matching entries number by total histogram entries to |
| 4990 | + * get the histogram related selectivity |
| 4991 | + */ |
| 4992 | +hissel /=nvalues; |
| 4993 | +} |
| 4994 | +} |
| 4995 | +else |
| 4996 | +{ |
| 4997 | +/* no histogram info available */ |
| 4998 | +values=NULL; |
| 4999 | +i=nvalues=0; |
| 5000 | +} |
| 5001 | + |
| 5002 | +free_attstatsslot(vardata.atttype,values,nvalues, |
| 5003 | +NULL,0); |
| 5004 | + |
| 5005 | + |
| 5006 | +/* |
| 5007 | + * calculate selectivity based on MCV and histogram result |
| 5008 | + * histogram selectivity needs to be scaled down if there are any |
| 5009 | + * most-common-values |
| 5010 | + */ |
| 5011 | +selec=mcvsel+hissel* (1.0-mcvsum); |
| 5012 | + |
| 5013 | +/* |
| 5014 | + * don't return 0.0 selectivity unless all table values are inside |
| 5015 | + * mcv |
| 5016 | + */ |
| 5017 | +if (selec==0.0&&mcvsum!=1.0) |
| 5018 | +selec=DEFAULT_PARENT_SEL; |
| 5019 | +} |
| 5020 | +else |
| 5021 | +selec=DEFAULT_PARENT_SEL; |
| 5022 | +} |
| 5023 | +else |
| 5024 | +selec=DEFAULT_PARENT_SEL; |
| 5025 | + |
| 5026 | +ReleaseVariableStats(vardata); |
| 5027 | + |
| 5028 | +/* result should be in range, but make sure... */ |
| 5029 | +CLAMP_PROBABILITY(selec); |
| 5030 | + |
| 5031 | +PG_RETURN_FLOAT8((float8)selec); |
| 5032 | +} |
| 5033 | + |