1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Fix a bunch of bad interactions between partial indexes and the new

planning logic for bitmap indexscans.  Partial indexes create corner
cases in which a scan might be done with no explicit index qual conditions,
and the code wasn't handling those cases nicely.  Also be a little
tenser about eliminating redundant clauses in the generated plan.
Per report from Dmitry Karasik.
This commit is contained in:
Tom Lane
2005-07-28 20:26:22 +00:00
parent 3535cb827a
commit a4ca842319
9 changed files with 399 additions and 83 deletions

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/list.c,v 1.64 2005/03/17 05:47:01 neilc Exp $
* $PostgreSQL: pgsql/src/backend/nodes/list.c,v 1.65 2005/07/28 20:26:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -686,9 +686,13 @@ list_delete_first(List *list)
* The returned list is newly-allocated, although the content of the
* cells is the same (i.e. any pointed-to objects are not copied).
*
* NB: Bizarrely, this function will NOT remove any duplicates that
* are present in list1 (so it is not really a union at all!). Also,
* this function could probably be implemented a lot faster if it is a
* NB: this function will NOT remove any duplicates that are present
* in list1 (so it only performs a "union" if list1 is known unique to
* start with). Also, if you are about to write "x = list_union(x, y)"
* you probably want to use list_concat_unique() instead to avoid wasting
* the list cells of the old x list.
*
* This function could probably be implemented a lot faster if it is a
* performance bottleneck.
*/
List *
@ -888,7 +892,153 @@ list_difference_oid(List *list1, List *list2)
return result;
}
/* Free all storage in a list, and optionally the pointed-to elements */
/*
* Append datum to list, but only if it isn't already in the list.
*
* Whether an element is already a member of the list is determined
* via equal().
*/
List *
list_append_unique(List *list, void *datum)
{
if (list_member(list, datum))
return list;
else
return lappend(list, datum);
}
/*
* This variant of list_append_unique() determines list membership via
* simple pointer equality.
*/
List *
list_append_unique_ptr(List *list, void *datum)
{
if (list_member_ptr(list, datum))
return list;
else
return lappend(list, datum);
}
/*
* This variant of list_append_unique() operates upon lists of integers.
*/
List *
list_append_unique_int(List *list, int datum)
{
if (list_member_int(list, datum))
return list;
else
return lappend_int(list, datum);
}
/*
* This variant of list_append_unique() operates upon lists of OIDs.
*/
List *
list_append_unique_oid(List *list, Oid datum)
{
if (list_member_oid(list, datum))
return list;
else
return lappend_oid(list, datum);
}
/*
* Append to list1 each member of list2 that isn't already in list1.
*
* Whether an element is already a member of the list is determined
* via equal().
*
* This is almost the same functionality as list_union(), but list1 is
* modified in-place rather than being copied. Note also that list2's cells
* are not inserted in list1, so the analogy to list_concat() isn't perfect.
*/
List *
list_concat_unique(List *list1, List *list2)
{
ListCell *cell;
Assert(IsPointerList(list1));
Assert(IsPointerList(list2));
foreach(cell, list2)
{
if (!list_member(list1, lfirst(cell)))
list1 = lappend(list1, lfirst(cell));
}
check_list_invariants(list1);
return list1;
}
/*
* This variant of list_concat_unique() determines list membership via
* simple pointer equality.
*/
List *
list_concat_unique_ptr(List *list1, List *list2)
{
ListCell *cell;
Assert(IsPointerList(list1));
Assert(IsPointerList(list2));
foreach(cell, list2)
{
if (!list_member_ptr(list1, lfirst(cell)))
list1 = lappend(list1, lfirst(cell));
}
check_list_invariants(list1);
return list1;
}
/*
* This variant of list_concat_unique() operates upon lists of integers.
*/
List *
list_concat_unique_int(List *list1, List *list2)
{
ListCell *cell;
Assert(IsIntegerList(list1));
Assert(IsIntegerList(list2));
foreach(cell, list2)
{
if (!list_member_int(list1, lfirst_int(cell)))
list1 = lappend_int(list1, lfirst_int(cell));
}
check_list_invariants(list1);
return list1;
}
/*
* This variant of list_concat_unique() operates upon lists of OIDs.
*/
List *
list_concat_unique_oid(List *list1, List *list2)
{
ListCell *cell;
Assert(IsOidList(list1));
Assert(IsOidList(list2));
foreach(cell, list2)
{
if (!list_member_oid(list1, lfirst_oid(cell)))
list1 = lappend_oid(list1, lfirst_oid(cell));
}
check_list_invariants(list1);
return list1;
}
/*
* Free all storage in a list, and optionally the pointed-to elements
*/
static void
list_free_private(List *list, bool deep)
{