Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitecc27d5

Browse files
committed
Support boolean columns in functional-dependency statistics.
There's no good reason that the multicolumn stats stuff shouldn't work onbooleans. But it looked only for "Var = pseudoconstant" clauses, and itwill seldom find those for boolean Vars, since earlier phases of planningwill fold "boolvar = true" or "boolvar = false" to just "boolvar" or"NOT boolvar" respectively. Improve dependencies_clauselist_selectivity()to recognize such clauses as equivalent to equality restrictions.This fixes a failure of the extended stats mechanism to apply in a casereported by Vitaliy Garnashevich. It's not a complete solution to hisproblem because the bitmap-scan costing code isn't consulting extendedstats where it should, but that's surely an independent issue.In passing, improve some comments, get rid of a NumRelids() test that'sredundant with the preceding bms_membership() test, and fixdependencies_clauselist_selectivity() so that estimatedclauses actuallyis a pure output argument as stated by its API contract.Back-patch to v10 where this code was introduced.Discussion:https://postgr.es/m/73a4936d-2814-dc08-ed0c-978f76f435b0@gmail.com
1 parent9f4992e commitecc27d5

File tree

1 file changed

+63
-47
lines changed

1 file changed

+63
-47
lines changed

‎src/backend/statistics/dependencies.c

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -736,91 +736,104 @@ pg_dependencies_send(PG_FUNCTION_ARGS)
736736
* dependency_is_compatible_clause
737737
*Determines if the clause is compatible with functional dependencies
738738
*
739-
* Only OpExprs with two arguments using an equality operator are supported.
740-
* When returning True attnum is set to the attribute number of the Var within
741-
* the supported clause.
742-
*
743-
* Currently we only support Var = Const, or Const = Var. It may be possible
744-
* to expand on this later.
739+
* Only clauses that have the form of equality to a pseudoconstant, or can be
740+
* interpreted that way, are currently accepted. Furthermore the variable
741+
* part of the clause must be a simple Var belonging to the specified
742+
* relation, whose attribute number we return in *attnum on success.
745743
*/
746744
staticbool
747745
dependency_is_compatible_clause(Node*clause,Indexrelid,AttrNumber*attnum)
748746
{
749747
RestrictInfo*rinfo= (RestrictInfo*)clause;
748+
Var*var;
750749

751750
if (!IsA(rinfo,RestrictInfo))
752751
return false;
753752

754-
/* Pseudoconstants are notreallyinterestinghere. */
753+
/* Pseudoconstants are not interesting(they couldn't contain a Var) */
755754
if (rinfo->pseudoconstant)
756755
return false;
757756

758-
/*clauses referencing multiple varnos are incompatible */
757+
/*Clauses referencing multiple, or no, varnos are incompatible */
759758
if (bms_membership(rinfo->clause_relids)!=BMS_SINGLETON)
760759
return false;
761760

762761
if (is_opclause(rinfo->clause))
763762
{
763+
/* If it's an opclause, check for Var = Const or Const = Var. */
764764
OpExpr*expr= (OpExpr*)rinfo->clause;
765-
Var*var;
766-
boolvaronleft= true;
767-
boolok;
768765

769-
/* Only expressions with two arguments areconsidered compatible. */
766+
/* Only expressions with two arguments arecandidates. */
770767
if (list_length(expr->args)!=2)
771768
return false;
772769

773-
/* see if it actually has the right */
774-
ok= (NumRelids((Node*)expr)==1)&&
775-
(is_pseudo_constant_clause(lsecond(expr->args))||
776-
(varonleft= false,
777-
is_pseudo_constant_clause(linitial(expr->args))));
778-
779-
/* unsupported structure (two variables or so) */
780-
if (!ok)
770+
/* Make sure non-selected argument is a pseudoconstant. */
771+
if (is_pseudo_constant_clause(lsecond(expr->args)))
772+
var=linitial(expr->args);
773+
elseif (is_pseudo_constant_clause(linitial(expr->args)))
774+
var=lsecond(expr->args);
775+
else
781776
return false;
782777

783778
/*
784-
* If it's not "=" operator, just ignore the clause, as it's not
779+
* If it's notan"=" operator, just ignore the clause, as it's not
785780
* compatible with functional dependencies.
786781
*
787782
* This uses the function for estimating selectivity, not the operator
788783
* directly (a bit awkward, but well ...).
784+
*
785+
* XXX this is pretty dubious; probably it'd be better to check btree
786+
* or hash opclass membership, so as not to be fooled by custom
787+
* selectivity functions, and to be more consistent with decisions
788+
* elsewhere in the planner.
789789
*/
790790
if (get_oprrest(expr->opno)!=F_EQSEL)
791791
return false;
792792

793-
var= (varonleft) ?linitial(expr->args) :lsecond(expr->args);
794-
793+
/* OK to proceed with checking "var" */
794+
}
795+
elseif (not_clause((Node*)rinfo->clause))
796+
{
795797
/*
796-
* We may ignore any RelabelType node above the operand. (There won't
797-
* be more than one, since eval_const_expressions() has been applied
798-
* already.)
798+
* "NOT x" can be interpreted as "x = false", so get the argument and
799+
* proceed with seeing if it's a suitable Var.
799800
*/
800-
if (IsA(var,RelabelType))
801-
var= (Var*) ((RelabelType*)var)->arg;
801+
var= (Var*)get_notclausearg(rinfo->clause);
802+
}
803+
else
804+
{
805+
/*
806+
* A boolean expression "x" can be interpreted as "x = true", so
807+
* proceed with seeing if it's a suitable Var.
808+
*/
809+
var= (Var*)rinfo->clause;
810+
}
802811

803-
/* We only support plain Vars for now */
804-
if (!IsA(var,Var))
805-
return false;
812+
/*
813+
* We may ignore any RelabelType node above the operand. (There won't be
814+
* more than one, since eval_const_expressions has been applied already.)
815+
*/
816+
if (IsA(var,RelabelType))
817+
var= (Var*) ((RelabelType*)var)->arg;
806818

807-
/*Ensure var is from the correct relation */
808-
if (var->varno!=relid)
809-
return false;
819+
/*We only support plain Vars for now */
820+
if (!IsA(var,Var))
821+
return false;
810822

811-
/*we also better ensure theVar is from thecurrent level */
812-
if (var->varlevelsup>0)
813-
return false;
823+
/*EnsureVar is from thecorrect relation */
824+
if (var->varno!=relid)
825+
return false;
814826

815-
/*Also skip system attributes (we don't allow stats on those). */
816-
if (!AttrNumberIsForUserDefinedAttr(var->varattno))
817-
return false;
827+
/*We also better ensure the Var is from the current level */
828+
if (var->varlevelsup!=0)
829+
return false;
818830

819-
*attnum=var->varattno;
820-
return true;
821-
}
831+
/* Also ignore system attributes (we don't allow stats on those) */
832+
if (!AttrNumberIsForUserDefinedAttr(var->varattno))
833+
return false;
822834

823-
return false;
835+
*attnum=var->varattno;
836+
return true;
824837
}
825838

826839
/*
@@ -891,12 +904,12 @@ find_strongest_dependency(StatisticExtInfo *stats, MVDependencies *dependencies,
891904

892905
/*
893906
* dependencies_clauselist_selectivity
894-
*Return the estimated selectivity of the given clauses using
895-
*functional dependency statistics, or 1.0 if no useful functional
907+
*Return the estimated selectivity of(a subset of)the given clauses
908+
*usingfunctional dependency statistics, or 1.0 if no useful functional
896909
*dependency statistic exists.
897910
*
898911
* 'estimatedclauses' is an output argument that gets a bit set corresponding
899-
* to the (zero-based) list index ofclausesthatare included in the
912+
* to the (zero-based) list index ofeach clausethatis included in the
900913
* estimated selectivity.
901914
*
902915
* Given equality clauses on attributes (a,b) we find the strongest dependency
@@ -932,6 +945,9 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
932945
AttrNumber*list_attnums;
933946
intlistidx;
934947

948+
/* initialize output argument */
949+
*estimatedclauses=NULL;
950+
935951
/* check if there's any stats that might be useful for us. */
936952
if (!has_stats_of_kind(rel->statlist,STATS_EXT_DEPENDENCIES))
937953
return1.0;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp