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

Commit2ef99ee

Browse files
committed
Planner wasn't correctly handling adjustment of tuple_fraction for the
case of LIMIT in a sub-select.
1 parent7db692c commit2ef99ee

File tree

1 file changed

+102
-58
lines changed

1 file changed

+102
-58
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 102 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.102 2001/03/22 03:59:37 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.103 2001/04/01 22:37:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -874,84 +874,128 @@ grouping_planner(Query *parse, double tuple_fraction)
874874

875875
/*
876876
* Figure out whether we expect to retrieve all the tuples that
877-
* the plan can generate, or to stop early due toa LIMIT or other
878-
*factors. If the caller passed a value >= 0, believe that
879-
* value, else do our own examination of the query context.
877+
* the plan can generate, or to stop early due tooutside factors
878+
*such as a cursor. If the caller passed a value >= 0, believe
879+
*thatvalue, else do our own examination of the query context.
880880
*/
881881
if (tuple_fraction<0.0)
882882
{
883883
/* Initial assumption is we need all the tuples */
884884
tuple_fraction=0.0;
885885

886886
/*
887-
* Check for a LIMIT clause.
887+
* Check for retrieve-into-portal, ie DECLARE CURSOR.
888+
*
889+
* We have no real idea how many tuples the user will ultimately
890+
* FETCH from a cursor, but it seems a good bet that he
891+
* doesn't want 'em all. Optimize for 10% retrieval (you
892+
* gotta better number? Should this be a SETtable parameter?)
893+
*/
894+
if (parse->isPortal)
895+
tuple_fraction=0.10;
896+
}
897+
898+
/*
899+
* Adjust tuple_fraction if we see that we are going to apply
900+
* limiting/grouping/aggregation/etc. This is not overridable by
901+
* the caller, since it reflects plan actions that this routine
902+
* will certainly take, not assumptions about context.
903+
*/
904+
if (parse->limitCount!=NULL)
905+
{
906+
/*
907+
* A LIMIT clause limits the absolute number of tuples returned.
908+
* However, if it's not a constant LIMIT then we have to punt;
909+
* for lack of a better idea, assume 10% of the plan's result
910+
* is wanted.
888911
*/
889-
if (parse->limitCount!=NULL)
912+
doublelimit_fraction=0.0;
913+
914+
if (IsA(parse->limitCount,Const))
890915
{
891-
if (IsA(parse->limitCount,Const))
916+
Const*limitc= (Const*)parse->limitCount;
917+
int32count=DatumGetInt32(limitc->constvalue);
918+
919+
/*
920+
* A NULL-constant LIMIT represents "LIMIT ALL", which
921+
* we treat the same as no limit (ie, expect to
922+
* retrieve all the tuples).
923+
*/
924+
if (!limitc->constisnull&&count>0)
892925
{
893-
Const*limitc= (Const*)parse->limitCount;
894-
int32count=DatumGetInt32(limitc->constvalue);
895-
896-
/*
897-
* A NULL-constant LIMIT represents "LIMIT ALL", which
898-
* we treat the same as no limit (ie, expect to
899-
* retrieve all the tuples).
900-
*/
901-
if (!limitc->constisnull&&count>0)
926+
limit_fraction= (double)count;
927+
/* We must also consider the OFFSET, if present */
928+
if (parse->limitOffset!=NULL)
902929
{
903-
tuple_fraction= (double)count;
904-
/* We must also consider the OFFSET, if present */
905-
if (parse->limitOffset!=NULL)
930+
if (IsA(parse->limitOffset,Const))
931+
{
932+
int32offset;
933+
934+
limitc= (Const*)parse->limitOffset;
935+
offset=DatumGetInt32(limitc->constvalue);
936+
if (!limitc->constisnull&&offset>0)
937+
limit_fraction+= (double)offset;
938+
}
939+
else
906940
{
907-
if (IsA(parse->limitOffset,Const))
908-
{
909-
int32offset;
910-
911-
limitc= (Const*)parse->limitOffset;
912-
offset=DatumGetInt32(limitc->constvalue);
913-
if (!limitc->constisnull&&offset>0)
914-
tuple_fraction+= (double)offset;
915-
}
916-
else
917-
{
918-
/* It's an expression ... punt ... */
919-
tuple_fraction=0.10;
920-
}
941+
/* OFFSET is an expression ... punt ... */
942+
limit_fraction=0.10;
921943
}
922944
}
923945
}
946+
}
947+
else
948+
{
949+
/* LIMIT is an expression ... punt ... */
950+
limit_fraction=0.10;
951+
}
952+
953+
if (limit_fraction>0.0)
954+
{
955+
/*
956+
* If we have absolute limits from both caller and LIMIT,
957+
* use the smaller value; if one is fractional and the other
958+
* absolute, treat the fraction as a fraction of the absolute
959+
* value; else we can multiply the two fractions together.
960+
*/
961+
if (tuple_fraction >=1.0)
962+
{
963+
if (limit_fraction >=1.0)
964+
{
965+
/* both absolute */
966+
tuple_fraction=Min(tuple_fraction,limit_fraction);
967+
}
968+
else
969+
{
970+
/* caller absolute, limit fractional */
971+
tuple_fraction *=limit_fraction;
972+
if (tuple_fraction<1.0)
973+
tuple_fraction=1.0;
974+
}
975+
}
976+
elseif (tuple_fraction>0.0)
977+
{
978+
if (limit_fraction >=1.0)
979+
{
980+
/* caller fractional, limit absolute */
981+
tuple_fraction *=limit_fraction;
982+
if (tuple_fraction<1.0)
983+
tuple_fraction=1.0;
984+
}
985+
else
986+
{
987+
/* both fractional */
988+
tuple_fraction *=limit_fraction;
989+
}
990+
}
924991
else
925992
{
926-
927-
/*
928-
* COUNT is an expression ... don't know exactly what
929-
* the limit will be, but for lack of a better idea
930-
* assume 10% of the plan's result is wanted.
931-
*/
932-
tuple_fraction=0.10;
993+
/* no info from caller, just use limit */
994+
tuple_fraction=limit_fraction;
933995
}
934996
}
935-
936-
/*
937-
* If no LIMIT, check for retrieve-into-portal, ie DECLARE
938-
* CURSOR.
939-
*
940-
* We have no real idea how many tuples the user will ultimately
941-
* FETCH from a cursor, but it seems a good bet that he
942-
* doesn't want 'em all. Optimize for 10% retrieval (you
943-
* gotta better number?)
944-
*/
945-
elseif (parse->isPortal)
946-
tuple_fraction=0.10;
947997
}
948998

949-
/*
950-
* Adjust tuple_fraction if we see that we are going to apply
951-
* grouping/aggregation/etc. This is not overridable by the
952-
* caller, since it reflects plan actions that this routine will
953-
* certainly take, not assumptions about context.
954-
*/
955999
if (parse->groupClause)
9561000
{
9571001

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp