aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/bitmapset.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-01-27 19:26:38 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-01-27 19:26:38 -0500
commite2fa76d80ba571d4de8992de6386536867250474 (patch)
treef2101a671cde7cf9859cc7c37b08e5daf50b428e /src/backend/nodes/bitmapset.c
parentb376ec6fa57bc76037014ede29498e2d1611968e (diff)
downloadpostgresql-e2fa76d80ba571d4de8992de6386536867250474.tar.gz
postgresql-e2fa76d80ba571d4de8992de6386536867250474.zip
Use parameterized paths to generate inner indexscans more flexibly.
This patch fixes the planner so that it can generate nestloop-with- inner-indexscan plans even with one or more levels of joining between the indexscan and the nestloop join that is supplying the parameter. The executor was fixed to handle such cases some time ago, but the planner was not ready. This should improve our plans in many situations where join ordering restrictions formerly forced complete table scans. There is probably a fair amount of tuning work yet to be done, because of various heuristics that have been added to limit the number of parameterized paths considered. However, we are not going to find out what needs to be adjusted until the code gets some real-world use, so it's time to get it in there where it can be tested easily. Note API change for index AM amcostestimate functions. I'm not aware of any non-core index AMs, but if there are any, they will need minor adjustments.
Diffstat (limited to 'src/backend/nodes/bitmapset.c')
-rw-r--r--src/backend/nodes/bitmapset.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 3b5fb20964e..4c904e03296 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -336,6 +336,83 @@ bms_is_subset(const Bitmapset *a, const Bitmapset *b)
}
/*
+ * bms_subset_compare - compare A and B for equality/subset relationships
+ *
+ * This is more efficient than testing bms_is_subset in both directions.
+ */
+BMS_Comparison
+bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
+{
+ BMS_Comparison result;
+ int shortlen;
+ int longlen;
+ int i;
+
+ /* Handle cases where either input is NULL */
+ if (a == NULL)
+ {
+ if (b == NULL)
+ return BMS_EQUAL;
+ return bms_is_empty(b) ? BMS_EQUAL : BMS_SUBSET1;
+ }
+ if (b == NULL)
+ return bms_is_empty(a) ? BMS_EQUAL : BMS_SUBSET2;
+ /* Check common words */
+ result = BMS_EQUAL; /* status so far */
+ shortlen = Min(a->nwords, b->nwords);
+ for (i = 0; i < shortlen; i++)
+ {
+ bitmapword aword = a->words[i];
+ bitmapword bword = b->words[i];
+
+ if ((aword & ~bword) != 0)
+ {
+ /* a is not a subset of b */
+ if (result == BMS_SUBSET1)
+ return BMS_DIFFERENT;
+ result = BMS_SUBSET2;
+ }
+ if ((bword & ~aword) != 0)
+ {
+ /* b is not a subset of a */
+ if (result == BMS_SUBSET2)
+ return BMS_DIFFERENT;
+ result = BMS_SUBSET1;
+ }
+ }
+ /* Check extra words */
+ if (a->nwords > b->nwords)
+ {
+ longlen = a->nwords;
+ for (; i < longlen; i++)
+ {
+ if (a->words[i] != 0)
+ {
+ /* a is not a subset of b */
+ if (result == BMS_SUBSET1)
+ return BMS_DIFFERENT;
+ result = BMS_SUBSET2;
+ }
+ }
+ }
+ else if (a->nwords < b->nwords)
+ {
+ longlen = b->nwords;
+ for (; i < longlen; i++)
+ {
+ if (b->words[i] != 0)
+ {
+ /* b is not a subset of a */
+ if (result == BMS_SUBSET2)
+ return BMS_DIFFERENT;
+ result = BMS_SUBSET1;
+ }
+ }
+ }
+ return result;
+}
+
+/*
* bms_is_member - is X a member of A?
*/
bool