37 #include "utils/fmgroids.h"
89 #define compare_range_bounds(partnatts, partsupfunc, partcollations, \
91 (partition_rbound_cmp(partnatts, partsupfunc, partcollations, \
92 (bound1)->datums, (bound1)->kind, (bound1)->lower, \
131 bool outer_has_default,
132 bool inner_has_default,
140 bool outer_has_default,
141 bool inner_has_default,
158 bool outer_has_default,
159 bool inner_has_default,
169 int nmerged,
List *merged_indexes);
180 List *merged_indexes,
198 int *lb_cmpval,
int *ub_cmpval);
205 int lb_cmpval,
int ub_cmpval,
213 List **merged_datums,
215 List **merged_indexes);
257 switch (
key->strategy)
323 *mapping = (
int *)
palloc(
sizeof(
int) * nparts);
324 for (
i = 0;
i < nparts;
i++)
327 switch (
key->strategy)
354 int greatest_modulus;
368 for (
i = 0;
i < nparts;
i++)
373 elog(
ERROR,
"invalid strategy in partition bound spec");
385 greatest_modulus = hbounds[nparts - 1].
modulus;
389 boundinfo->
kind = NULL;
391 boundinfo->
nindexes = greatest_modulus;
392 boundinfo->
indexes = (
int *)
palloc(greatest_modulus *
sizeof(
int));
393 for (
i = 0;
i < greatest_modulus;
i++)
408 for (
i = 0;
i < nparts;
i++)
413 boundinfo->
datums[
i] = &boundDatums[
i * 2];
417 while (remainder < greatest_modulus)
422 remainder += modulus;
425 (*mapping)[hbounds[
i].
index] =
i;
442 for (
i = 0;
i < nparts;
i++)
446 foreach(lc, boundspecs[
i]->listdatums)
450 if (!
val->constisnull)
472 int default_index = -1;
488 for (
j = 0,
i = 0;
i < nparts;
i++)
494 elog(
ERROR,
"invalid strategy in partition bound spec");
511 if (!
val->constisnull)
523 if (null_index != -1)
524 elog(
ERROR,
"found null more than once");
538 boundinfo->
kind = NULL;
556 for (
i = 0;
i < ndatums;
i++)
558 int orig_index = all_values[
i].
index;
560 boundinfo->
datums[
i] = &boundDatums[
i];
562 key->parttypbyval[0],
566 if ((*mapping)[orig_index] == -1)
567 (*mapping)[orig_index] = next_index++;
569 boundinfo->
indexes[
i] = (*mapping)[orig_index];
582 if (null_index != -1)
585 if ((*mapping)[null_index] == -1)
586 (*mapping)[null_index] = next_index++;
587 boundinfo->
null_index = (*mapping)[null_index];
591 if (default_index != -1)
598 Assert(default_index >= 0);
599 Assert((*mapping)[default_index] == -1);
600 (*mapping)[default_index] = next_index++;
638 if (
index < last_index)
669 Assert(next_index == nparts);
689 int default_index = -1;
707 for (
i = 0;
i < nparts;
i++)
714 elog(
ERROR,
"invalid strategy in partition bound spec");
729 all_bounds[ndatums++] =
lower;
730 all_bounds[ndatums++] =
upper;
733 Assert(ndatums == nparts * 2 ||
734 (default_index != -1 && ndatums == (nparts - 1) * 2));
747 for (
i = 0;
i < ndatums;
i++)
750 bool is_distinct =
false;
754 for (
j = 0;
j <
key->partnatts;
j++)
758 if (prev == NULL ||
cur->kind[
j] != prev->
kind[
j])
773 key->partcollation[
j],
788 rbounds[k++] = all_bounds[
i];
818 boundinfo->
indexes = (
int *)
palloc((ndatums + 1) *
sizeof(int));
826 partnatts =
key->partnatts;
831 for (
i = 0;
i < ndatums;
i++)
835 boundinfo->
datums[
i] = &boundDatums[
i * partnatts];
836 boundinfo->
kind[
i] = &boundKinds[
i * partnatts];
837 for (
j = 0;
j < partnatts;
j++)
842 key->parttypbyval[
j],
859 int orig_index = rbounds[
i]->
index;
862 if ((*mapping)[orig_index] == -1)
863 (*mapping)[orig_index] = next_index++;
865 boundinfo->
indexes[
i] = (*mapping)[orig_index];
872 if (default_index != -1)
874 Assert(default_index >= 0 && (*mapping)[default_index] == -1);
875 (*mapping)[default_index] = next_index++;
884 Assert(next_index == nparts);
942 #ifdef USE_ASSERT_CHECKING
954 for (
j = 0;
j < partnatts;
j++)
957 if (b1->
kind != NULL)
985 parttypbyval[
j], parttyplen[
j]))
1020 partnatts =
key->partnatts;
1027 if (src->
kind != NULL)
1045 for (
i = 0;
i < ndatums;
i++)
1047 dest->kind[
i] = &boundKinds[
i * partnatts];
1063 natts = hash_part ? 2 : partnatts;
1064 boundDatums =
palloc(ndatums * natts *
sizeof(
Datum));
1066 for (
i = 0;
i < ndatums;
i++)
1070 dest->datums[
i] = &boundDatums[
i * natts];
1072 for (
j = 0;
j < natts;
j++)
1079 typlen =
sizeof(
int32);
1084 byval =
key->parttypbyval[
j];
1085 typlen =
key->parttyplen[
j];
1088 if (
dest->kind == NULL ||
1095 dest->indexes = (
int *)
palloc(
sizeof(
int) * nindexes);
1096 memcpy(
dest->indexes, src->
indexes,
sizeof(
int) * nindexes);
1123 List **outer_parts,
List **inner_parts)
1134 Assert(outer_rel->boundinfo->strategy == inner_rel->boundinfo->strategy);
1136 *outer_parts = *inner_parts =
NIL;
1137 switch (outer_rel->boundinfo->strategy)
1202 List **outer_parts,
List **inner_parts)
1218 int null_index = -1;
1219 int default_index = -1;
1238 outer_has_default =
false;
1240 inner_has_default =
false;
1249 outer_pos = inner_pos = 0;
1250 while (outer_pos < outer_bi->ndatums || inner_pos < inner_bi->ndatums)
1252 int outer_index = -1;
1253 int inner_index = -1;
1254 Datum *outer_datums;
1255 Datum *inner_datums;
1257 Datum *merged_datum = NULL;
1258 int merged_index = -1;
1260 if (outer_pos < outer_bi->ndatums)
1266 outer_index = outer_bi->
indexes[outer_pos];
1273 if (inner_pos < inner_bi->ndatums)
1279 inner_index = inner_bi->
indexes[inner_pos];
1288 outer_datums = outer_pos < outer_bi->
ndatums ?
1289 outer_bi->
datums[outer_pos] : NULL;
1290 inner_datums = inner_pos < inner_bi->
ndatums ?
1291 inner_bi->
datums[inner_pos] : NULL;
1302 if (outer_pos >= outer_bi->
ndatums)
1304 else if (inner_pos >= inner_bi->
ndatums)
1308 Assert(outer_datums != NULL && inner_datums != NULL);
1318 Assert(outer_pos < outer_bi->ndatums);
1319 Assert(inner_pos < inner_bi->ndatums);
1320 Assert(outer_index >= 0);
1321 Assert(inner_index >= 0);
1328 outer_index, inner_index,
1330 if (merged_index == -1)
1333 merged_datum = outer_datums;
1339 else if (cmpval < 0)
1342 Assert(outer_pos < outer_bi->ndatums);
1353 outer_index = outer_bi->
indexes[outer_pos];
1354 Assert(outer_index >= 0);
1364 if (merged_index == -1)
1366 merged_datum = outer_datums;
1376 Assert(inner_pos < inner_bi->ndatums);
1384 if (outer_has_default || jointype ==
JOIN_FULL)
1387 inner_index = inner_bi->
indexes[inner_pos];
1388 Assert(inner_index >= 0);
1398 if (merged_index == -1)
1400 merged_datum = inner_datums;
1411 if (merged_index >= 0 && merged_index != default_index)
1413 merged_datums =
lappend(merged_datums, merged_datum);
1414 merged_indexes =
lappend_int(merged_indexes, merged_index);
1422 if (outer_has_null &&
1424 outer_has_null =
false;
1425 if (inner_has_null &&
1427 inner_has_null =
false;
1430 if (outer_has_null || inner_has_null)
1432 outer_has_null, inner_has_null,
1434 jointype, &next_index, &null_index);
1436 Assert(null_index == -1);
1439 if (outer_has_default || inner_has_default)
1441 outer_has_default, inner_has_default,
1442 outer_default, inner_default,
1443 jointype, &next_index, &default_index);
1445 Assert(default_index == -1);
1455 next_index, merged_indexes);
1460 &outer_map, &inner_map,
1462 outer_parts, inner_parts);
1485 return merged_bounds;
1508 Oid *partcollations,
1511 List **outer_parts,
List **inner_parts)
1531 int default_index = -1;
1549 outer_has_default =
false;
1551 inner_has_default =
false;
1562 outer_lb_pos = inner_lb_pos = 0;
1564 &outer_lb, &outer_ub);
1566 &inner_lb, &inner_ub);
1567 while (outer_index >= 0 || inner_index >= 0)
1574 int merged_index = -1;
1585 if (outer_index == -1)
1591 else if (inner_index == -1)
1600 &outer_lb, &outer_ub,
1601 &inner_lb, &inner_ub,
1602 &lb_cmpval, &ub_cmpval);
1612 Assert(outer_index >= 0);
1614 outer_map.
merged[outer_index] ==
false);
1615 Assert(inner_index >= 0);
1617 inner_map.
merged[inner_index] ==
false);
1624 outer_index, inner_index,
1626 Assert(merged_index >= 0);
1630 partcollations, jointype,
1631 &outer_lb, &outer_ub,
1632 &inner_lb, &inner_ub,
1633 lb_cmpval, ub_cmpval,
1634 &merged_lb, &merged_ub);
1637 save_outer_ub = outer_ub;
1638 save_inner_ub = inner_ub;
1642 &outer_lb, &outer_ub);
1644 &inner_lb, &inner_ub);
1653 if (ub_cmpval > 0 && inner_index >= 0 &&
1655 &save_outer_ub, &inner_lb) > 0)
1657 if (ub_cmpval < 0 && outer_index >= 0 &&
1659 &outer_lb, &save_inner_ub) < 0)
1668 if ((outer_has_default && (lb_cmpval > 0 || ub_cmpval < 0)) ||
1669 (inner_has_default && (lb_cmpval < 0 || ub_cmpval > 0)))
1672 else if (ub_cmpval < 0)
1677 Assert(outer_index >= 0);
1679 outer_map.
merged[outer_index] ==
false);
1698 if (merged_index == -1)
1700 merged_lb = outer_lb;
1701 merged_ub = outer_ub;
1706 &outer_lb, &outer_ub);
1714 Assert(inner_index >= 0);
1716 inner_map.
merged[inner_index] ==
false);
1724 if (outer_has_default || jointype ==
JOIN_FULL)
1735 if (merged_index == -1)
1737 merged_lb = inner_lb;
1738 merged_ub = inner_ub;
1743 &inner_lb, &inner_ub);
1750 if (merged_index >= 0 && merged_index != default_index)
1752 &merged_lb, &merged_ub, merged_index,
1753 &merged_datums, &merged_kinds,
1758 if (outer_has_default || inner_has_default)
1760 outer_has_default, inner_has_default,
1761 outer_default, inner_default,
1762 jointype, &next_index, &default_index);
1764 Assert(default_index == -1);
1778 &outer_map, &inner_map,
1780 outer_parts, inner_parts);
1804 return merged_bounds;
1814 int nparts = rel->
nparts;
1822 for (
i = 0;
i < nparts;
i++)
1849 part_rel = rel->part_rels[part_index];
1864 int outer_index,
int inner_index,
int *next_index)
1866 int outer_merged_index;
1867 int inner_merged_index;
1871 Assert(outer_index >= 0 && outer_index < outer_map->nparts);
1873 outer_merged = outer_map->
merged[outer_index];
1874 Assert(inner_index >= 0 && inner_index < inner_map->nparts);
1876 inner_merged = inner_map->
merged[inner_index];
1882 if (outer_merged_index >= 0 && inner_merged_index >= 0)
1891 if (outer_merged_index == inner_merged_index)
1895 return outer_merged_index;
1897 if (!outer_merged && !inner_merged)
1906 if (outer_merged_index < inner_merged_index)
1908 outer_map->
merged[outer_index] =
true;
1910 inner_map->
merged[inner_index] =
true;
1912 inner_map->
old_indexes[inner_index] = inner_merged_index;
1913 return outer_merged_index;
1917 inner_map->
merged[inner_index] =
true;
1919 outer_map->
merged[outer_index] =
true;
1921 outer_map->
old_indexes[outer_index] = outer_merged_index;
1922 return inner_merged_index;
1929 Assert(outer_merged_index == -1 || inner_merged_index == -1);
1937 if (outer_merged_index == -1 && inner_merged_index == -1)
1939 int merged_index = *next_index;
1944 outer_map->
merged[outer_index] =
true;
1946 inner_map->
merged[inner_index] =
true;
1947 *next_index = *next_index + 1;
1948 return merged_index;
1950 if (outer_merged_index >= 0 && !outer_map->
merged[outer_index])
1952 Assert(inner_merged_index == -1);
1955 inner_map->
merged[inner_index] =
true;
1956 outer_map->
merged[outer_index] =
true;
1957 return outer_merged_index;
1959 if (inner_merged_index >= 0 && !inner_map->
merged[inner_index])
1961 Assert(outer_merged_index == -1);
1964 outer_map->
merged[outer_index] =
true;
1965 inner_map->
merged[inner_index] =
true;
1966 return inner_merged_index;
1983 bool outer_has_default,
1984 bool inner_has_default,
1991 int merged_index = -1;
1993 Assert(outer_index >= 0);
2003 if (inner_has_default)
2005 Assert(inner_default >= 0);
2014 if (outer_has_default)
2018 outer_index, inner_default,
2020 if (merged_index == -1)
2033 if (*default_index == -1)
2034 *default_index = merged_index;
2036 Assert(*default_index == merged_index);
2046 if (merged_index == -1)
2050 return merged_index;
2065 bool outer_has_default,
2066 bool inner_has_default,
2073 int merged_index = -1;
2075 Assert(inner_index >= 0);
2085 if (outer_has_default)
2087 Assert(outer_default >= 0);
2096 if (inner_has_default)
2100 outer_default, inner_index,
2102 if (merged_index == -1)
2116 if (*default_index == -1)
2117 *default_index = merged_index;
2119 Assert(*default_index == merged_index);
2128 if (merged_index == -1)
2132 return merged_index;
2150 bool outer_has_null,
2151 bool inner_has_null,
2158 bool consider_outer_null =
false;
2159 bool consider_inner_null =
false;
2161 Assert(outer_has_null || inner_has_null);
2162 Assert(*null_index == -1);
2170 Assert(outer_null >= 0 && outer_null < outer_map->nparts);
2172 consider_outer_null =
true;
2176 Assert(inner_null >= 0 && inner_null < inner_map->nparts);
2178 consider_inner_null =
true;
2182 if (!consider_outer_null && !consider_inner_null)
2185 if (consider_outer_null && !consider_inner_null)
2204 else if (!consider_outer_null && consider_inner_null)
2222 Assert(consider_outer_null && consider_inner_null);
2243 outer_null, inner_null,
2245 Assert(*null_index >= 0);
2260 bool outer_has_default,
2261 bool inner_has_default,
2268 int outer_merged_index = -1;
2269 int inner_merged_index = -1;
2271 Assert(outer_has_default || inner_has_default);
2274 if (outer_has_default)
2276 Assert(outer_default >= 0 && outer_default < outer_map->nparts);
2279 if (inner_has_default)
2281 Assert(inner_default >= 0 && inner_default < inner_map->nparts);
2285 if (outer_has_default && !inner_has_default)
2298 if (outer_merged_index == -1)
2300 Assert(*default_index == -1);
2306 Assert(*default_index == outer_merged_index);
2309 Assert(*default_index == -1);
2311 else if (!outer_has_default && inner_has_default)
2323 if (inner_merged_index == -1)
2325 Assert(*default_index == -1);
2331 Assert(*default_index == inner_merged_index);
2334 Assert(*default_index == -1);
2338 Assert(outer_has_default && inner_has_default);
2347 Assert(outer_merged_index == -1);
2348 Assert(inner_merged_index == -1);
2349 Assert(*default_index == -1);
2355 Assert(*default_index >= 0);
2370 int merged_index = *next_index;
2377 *next_index = *next_index + 1;
2378 return merged_index;
2387 int nmerged,
List *merged_indexes)
2396 new_indexes = (
int *)
palloc(
sizeof(
int) * nmerged);
2397 for (
i = 0;
i < nmerged;
i++)
2398 new_indexes[
i] = -1;
2406 if (merged_index >= 0)
2415 if (merged_index >= 0)
2421 foreach(lc, merged_indexes)
2424 Assert(merged_index >= 0);
2425 if (new_indexes[merged_index] >= 0)
2443 List **outer_parts,
List **inner_parts)
2445 int outer_nparts = outer_map->
nparts;
2446 int inner_nparts = inner_map->
nparts;
2456 outer_indexes = (
int *)
palloc(
sizeof(
int) * nmerged);
2457 inner_indexes = (
int *)
palloc(
sizeof(
int) * nmerged);
2458 for (
i = 0;
i < nmerged;
i++)
2459 outer_indexes[
i] = inner_indexes[
i] = -1;
2464 max_nparts =
Max(outer_nparts, inner_nparts);
2465 for (
i = 0;
i < max_nparts;
i++)
2467 if (
i < outer_nparts)
2471 if (merged_index >= 0)
2473 Assert(merged_index < nmerged);
2474 outer_indexes[merged_index] =
i;
2477 if (
i < inner_nparts)
2481 if (merged_index >= 0)
2483 Assert(merged_index < nmerged);
2484 inner_indexes[merged_index] =
i;
2490 for (
i = 0;
i < nmerged;
i++)
2492 int outer_index = outer_indexes[
i];
2493 int inner_index = inner_indexes[
i];
2501 if (outer_index == -1 && inner_index == -1)
2504 *outer_parts =
lappend(*outer_parts, outer_index >= 0 ?
2505 outer_rel->part_rels[outer_index] : NULL);
2506 *inner_parts =
lappend(*inner_parts, inner_index >= 0 ?
2507 inner_rel->part_rels[inner_index] : NULL);
2510 pfree(outer_indexes);
2511 pfree(inner_indexes);
2520 List *merged_kinds,
List *merged_indexes,
2521 int null_index,
int default_index)
2529 merged_bounds->
strategy = strategy;
2530 merged_bounds->
ndatums = ndatums;
2534 foreach(lc, merged_datums)
2543 foreach(lc, merged_kinds)
2554 merged_bounds->
kind = NULL;
2562 merged_bounds->
indexes = (
int *)
palloc(
sizeof(
int) * ndatums);
2564 foreach(lc, merged_indexes)
2570 return merged_bounds;
2595 if (part_index == -1)
2633 if (*lb_pos + 2 >= bi->
ndatums)
2642 if (bi->
indexes[*lb_pos + 2] < 0)
2643 *lb_pos = *lb_pos + 2;
2645 *lb_pos = *lb_pos + 1;
2664 Oid *partcollations,
2669 int *lb_cmpval,
int *ub_cmpval)
2676 outer_ub, inner_lb) < 0)
2688 outer_lb, inner_ub) > 0)
2697 outer_lb, inner_lb);
2699 outer_ub, inner_ub);
2718 int lb_cmpval,
int ub_cmpval,
2723 outer_lb, inner_lb) == lb_cmpval);
2725 outer_ub, inner_ub) == ub_cmpval);
2738 *merged_lb = (lb_cmpval > 0) ? *outer_lb : *inner_lb;
2739 *merged_ub = (ub_cmpval < 0) ? *outer_ub : *inner_ub;
2750 *merged_lb = *outer_lb;
2751 *merged_ub = *outer_ub;
2762 *merged_lb = (lb_cmpval < 0) ? *outer_lb : *inner_lb;
2763 *merged_ub = (ub_cmpval > 0) ? *outer_ub : *inner_ub;
2767 elog(
ERROR,
"unrecognized join type: %d", (
int) jointype);
2777 Oid *partcollations,
2781 List **merged_datums,
2782 List **merged_kinds,
2783 List **merged_indexes)
2787 if (!*merged_datums)
2791 Assert(!*merged_indexes);
2806 prev_ub.
lower =
false;
2828 *merged_datums =
lappend(*merged_datums, merged_lb->
datums);
2829 *merged_kinds =
lappend(*merged_kinds, merged_lb->
kind);
2830 *merged_indexes =
lappend_int(*merged_indexes, -1);
2834 *merged_datums =
lappend(*merged_datums, merged_ub->
datums);
2835 *merged_kinds =
lappend(*merged_kinds, merged_ub->
kind);
2836 *merged_indexes =
lappend_int(*merged_indexes, merged_index);
2855 Assert(boundinfo != NULL);
2904 bool overlap =
false;
2905 int overlap_location = -1;
2920 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2921 errmsg(
"partition \"%s\" conflicts with existing default partition \"%s\"",
2926 switch (
key->strategy)
2933 if (partdesc->
nparts > 0)
2935 int greatest_modulus;
2970 if (next_modulus % spec->
modulus != 0)
2972 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2973 errmsg(
"every hash partition modulus must be a factor of the next larger modulus"),
2974 errdetail(
"The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".",
2989 if (spec->
modulus % prev_modulus != 0)
2991 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2992 errmsg(
"every hash partition modulus must be a factor of the next larger modulus"),
2993 errdetail(
"The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\".",
2998 if (offset + 1 < boundinfo->
ndatums)
3011 if (next_modulus % spec->
modulus != 0)
3013 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3014 errmsg(
"every hash partition modulus must be a factor of the next larger modulus"),
3015 errdetail(
"The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".",
3021 greatest_modulus = boundinfo->
nindexes;
3030 if (remainder >= greatest_modulus)
3031 remainder = remainder % greatest_modulus;
3036 if (boundinfo->
indexes[remainder] != -1)
3040 with = boundinfo->
indexes[remainder];
3044 }
while (remainder < greatest_modulus);
3054 if (partdesc->
nparts > 0)
3068 overlap_location =
val->location;
3069 if (!
val->constisnull)
3079 if (offset >= 0 &&
equal)
3082 with = boundinfo->
indexes[offset];
3127 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3128 errmsg(
"empty range bound specified for partition \"%s\"",
3130 errdetail(
"Specified lower bound %s is greater than or equal to upper bound %s.",
3136 if (partdesc->
nparts > 0)
3166 if (boundinfo->
indexes[offset + 1] < 0)
3174 if (offset + 1 < boundinfo->
ndatums)
3180 datums = boundinfo->
datums[offset + 1];
3181 kind = boundinfo->
kind[offset + 1];
3182 is_lower = (boundinfo->
indexes[offset + 1] == -1);
3204 overlap_location = datum->
location;
3205 with = boundinfo->
indexes[offset + 2];
3224 overlap_location = datum->
location;
3225 with = boundinfo->
indexes[offset + 1];
3237 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3238 errmsg(
"partition \"%s\" would overlap partition \"%s\"",
3255 List *new_part_constraints;
3256 List *def_part_constraints;
3263 def_part_constraints =
3270 def_part_constraints =
3282 (
errmsg_internal(
"updated partition constraint for default partition \"%s\" is implied by existing constraints",
3291 if (default_rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3297 foreach(lc, all_parts)
3301 Expr *partition_constraint;
3320 partition_constraint = (
Expr *)
3322 part_rel, default_rel);
3330 def_part_constraints))
3333 (
errmsg_internal(
"updated partition constraint for default partition \"%s\" is implied by existing constraints",
3342 part_rel = default_rel;
3350 if (part_rel->
rd_rel->relkind != RELKIND_RELATION)
3352 if (part_rel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE)
3354 (
errcode(ERRCODE_CHECK_VIOLATION),
3355 errmsg(
"skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"",
3385 if (!
ExecCheck(partqualstate, econtext))
3387 (
errcode(ERRCODE_CHECK_VIOLATION),
3388 errmsg(
"updated partition constraint for default partition \"%s\" would be violated by some row",
3456 if (
val->constisnull)
3457 elog(
ERROR,
"invalid range bound datum");
3499 bool lower2 = b2->
lower;
3501 for (
i = 0;
i < partnatts;
i++)
3512 if (kind1[
i] < kind2[
i])
3514 else if (kind1[
i] > kind2[
i])
3540 if (cmpval == 0 && lower1 != lower2)
3541 cmpval = lower1 ? 1 : -1;
3543 return cmpval == 0 ? 0 : (cmpval < 0 ? -colnum : colnum);
3559 Datum *tuple_datums,
int n_tuple_datums)
3564 for (
i = 0;
i < n_tuple_datums;
i++)
3590 if (modulus1 < modulus2)
3592 if (modulus1 > modulus2)
3594 if (modulus1 == modulus2 && remainder1 != remainder2)
3595 return (remainder1 > remainder2) ? 1 : -1;
3622 mid = (lo + hi + 1) / 2;
3625 boundinfo->
datums[mid][0],
3630 *is_equal = (cmpval == 0);
3667 mid = (lo + hi + 1) / 2;
3671 boundinfo->
kind[mid],
3672 (boundinfo->
indexes[mid] == -1),
3710 mid = (lo + hi + 1) / 2;
3714 boundinfo->
kind[mid],
3720 *is_equal = (cmpval == 0);
3740 int modulus,
int remainder)
3754 mid = (lo + hi + 1) / 2;
3758 modulus, remainder);
3801 key->partcollation[0],
3843 key->partopcintype[col],
3844 key->partopcintype[col],
3847 elog(
ERROR,
"missing operator %d(%u,%u) in partition opfamily %u",
3848 strategy,
key->partopcintype[col],
key->partopcintype[col],
3849 key->partopfamily[col]);
3856 *need_relabel = (
key->parttypid[col] !=
key->partopcintype[col] &&
3857 key->partopcintype[col] != RECORDOID &&
3858 !IsPolymorphicType(
key->partopcintype[col]));
3873 bool need_relabel =
false;
3874 Expr *result = NULL;
3886 key->partcollation[keynum] !=
key->parttypcoll[keynum]))
3888 key->partopcintype[keynum],
3890 key->partcollation[keynum],
3894 switch (
key->strategy)
3912 arrexpr->array_typeid =
3914 arrexpr->array_collid =
key->parttypcoll[keynum];
3915 arrexpr->element_typeid =
key->parttypid[keynum];
3917 arrexpr->multidims =
false;
3922 saopexpr->
opno = operoid;
3926 saopexpr->
useOr =
true;
3927 saopexpr->inputcollid =
key->partcollation[keynum];
3931 result = (
Expr *) saopexpr;
3948 key->partcollation[keynum]);
3949 elemops =
lappend(elemops, elemop);
3963 key->partcollation[keynum]);
3990 Node *remainderConst;
4024 for (
i = 0;
i <
key->partnatts;
i++)
4029 if (
key->partattrs[
i] != 0)
4035 key->parttypcoll[
i],
4041 partexprs_item =
lnext(
key->partexprs, partexprs_item);
4076 bool list_has_null =
false;
4085 if (
key->partattrs[0] != 0)
4090 key->parttypcoll[0],
4112 list_has_null =
true;
4119 if (ndatums == 0 && !list_has_null)
4122 for (
i = 0;
i < ndatums;
i++)
4133 key->parttypcoll[0],
4136 key->parttypbyval[0],
4137 key->parttyplen[0]),
4139 key->parttypbyval[0]);
4153 if (
val->constisnull)
4154 list_has_null =
true;
4167 keyCol, (
Expr *) elems);
4186 nulltest->
arg = keyCol;
4188 nulltest->argisrow =
false;
4200 nulltest->
arg = keyCol;
4202 nulltest->argisrow =
false;
4283 *partexprs_item_saved;
4292 List *lower_or_arms,
4297 *upper_or_start_datum;
4298 bool need_next_lower_arm,
4299 need_next_upper_arm;
4306 int nparts = pdesc->
nparts,
4309 for (k = 0; k < nparts; k++)
4311 Oid inhrelid = inhoids[k];
4318 elog(
ERROR,
"cache lookup failed for relation %u", inhrelid);
4321 Anum_pg_class_relpartbound);
4325 elog(
ERROR,
"expected PartitionBoundSpec");
4344 if (or_expr_args !=
NIL)
4346 Expr *other_parts_constr;
4354 other_parts_constr =
4391 partexprs_item_saved = partexprs_item;
4409 partexprs_item_saved = partexprs_item;
4414 &lower_val, &upper_val);
4422 if (!lower_val || !upper_val)
4430 (
Expr *) upper_val);
4448 if (
i ==
key->partnatts - 1)
4449 elog(
ERROR,
"invalid range bound specification");
4454 keyCol, (
Expr *) lower_val));
4460 lower_or_start_datum = cell1;
4461 upper_or_start_datum = cell2;
4464 num_or_arms =
key->partnatts -
i;
4466 lower_or_arms = upper_or_arms =
NIL;
4467 need_next_lower_arm = need_next_upper_arm =
true;
4468 while (current_or_arm < num_or_arms)
4470 List *lower_or_arm_args =
NIL,
4471 *upper_or_arm_args =
NIL;
4475 partexprs_item = partexprs_item_saved;
4481 *udatum_next = NULL;
4494 &lower_val, &upper_val);
4496 if (need_next_lower_arm && lower_val)
4506 if (
j -
i < current_or_arm)
4508 else if (
j ==
key->partnatts - 1 ||
4515 lower_or_arm_args =
lappend(lower_or_arm_args,
4519 (
Expr *) lower_val));
4522 if (need_next_upper_arm && upper_val)
4531 if (
j -
i < current_or_arm)
4533 else if (udatum_next &&
4539 upper_or_arm_args =
lappend(upper_or_arm_args,
4543 (
Expr *) upper_val));
4552 if (
j -
i > current_or_arm)
4558 if (!lower_val || !ldatum_next ||
4560 need_next_lower_arm =
false;
4561 if (!upper_val || !udatum_next ||
4563 need_next_upper_arm =
false;
4568 if (lower_or_arm_args !=
NIL)
4569 lower_or_arms =
lappend(lower_or_arms,
4574 if (upper_or_arm_args !=
NIL)
4575 upper_or_arms =
lappend(upper_or_arms,
4581 if (!need_next_lower_arm && !need_next_upper_arm)
4592 if (lower_or_arms !=
NIL)
4597 if (upper_or_arms !=
NIL)
4610 result = for_default
4641 if (
key->partattrs[keynum] != 0)
4644 key->partattrs[keynum],
4645 key->parttypid[keynum],
4646 key->parttypmod[keynum],
4647 key->parttypcoll[keynum],
4652 if (*partexprs_item == NULL)
4653 elog(
ERROR,
"wrong number of partition key expressions");
4655 *partexprs_item =
lnext(
key->partexprs, *partexprs_item);
4685 for (
i = 0;
i <
key->partnatts;
i++)
4689 if (
key->partattrs[
i] != 0)
4695 key->parttypcoll[
i],
4700 if (partexprs_item == NULL)
4701 elog(
ERROR,
"wrong number of partition key expressions");
4703 partexprs_item =
lnext(
key->partexprs, partexprs_item);
4707 nulltest->
arg = keyCol;
4709 nulltest->argisrow =
false;
4711 result =
lappend(result, nulltest);
4730 for (
i = 0;
i < partnatts;
i++)
4774 typedef struct ColumnsHashData
4779 int16 variadic_typlen;
4780 bool variadic_typbyval;
4781 char variadic_typalign;
4789 ColumnsHashData *my_extra;
4802 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4803 errmsg(
"modulus for hash partition must be an integer value greater than zero")));
4806 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4807 errmsg(
"remainder for hash partition must be an integer value greater than or equal to zero")));
4808 if (remainder >= modulus)
4810 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4811 errmsg(
"remainder for hash partition must be less than modulus")));
4816 my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra;
4817 if (my_extra == NULL || my_extra->relid != parentId)
4830 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4831 errmsg(
"\"%s\" is not a hash partitioned table",
4839 if (
key->partnatts != nargs)
4841 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4842 errmsg(
"number of partitioning columns (%d) does not match number of partition keys provided (%d)",
4843 key->partnatts, nargs)));
4846 fcinfo->flinfo->fn_extra =
4848 offsetof(ColumnsHashData, partsupfunc) +
4850 my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra;
4851 my_extra->relid = parentId;
4852 my_extra->nkeys =
key->partnatts;
4853 memcpy(my_extra->partcollid,
key->partcollation,
4854 key->partnatts *
sizeof(
Oid));
4857 for (
j = 0;
j <
key->partnatts; ++
j)
4863 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4864 errmsg(
"column %d of the partition key has type %s, but supplied value is of type %s",
4868 &
key->partsupfunc[
j],
4869 fcinfo->flinfo->fn_mcxt);
4877 fcinfo->flinfo->fn_extra =
4879 offsetof(ColumnsHashData, partsupfunc) +
4881 my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra;
4882 my_extra->relid = parentId;
4883 my_extra->nkeys =
key->partnatts;
4884 my_extra->variadic_type =
ARR_ELEMTYPE(variadic_array);
4886 &my_extra->variadic_typlen,
4887 &my_extra->variadic_typbyval,
4888 &my_extra->variadic_typalign);
4889 my_extra->partcollid[0] =
key->partcollation[0];
4892 for (
j = 0;
j <
key->partnatts; ++
j)
4893 if (
key->parttypid[
j] != my_extra->variadic_type)
4895 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4896 errmsg(
"column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"",
4902 &
key->partsupfunc[0],
4903 fcinfo->flinfo->fn_mcxt);
4912 int nkeys = my_extra->nkeys;
4921 for (
i = 0;
i < nkeys;
i++)
4932 my_extra->partcollid[
i],
4949 my_extra->variadic_type,
4950 my_extra->variadic_typlen,
4951 my_extra->variadic_typbyval,
4952 my_extra->variadic_typalign,
4953 &datum, &isnull, &nelems);
4956 if (nelems != my_extra->nkeys)
4958 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4959 errmsg(
"number of partitioning columns (%d) does not match number of partition keys provided (%d)",
4960 my_extra->nkeys, nelems)));
4962 for (
i = 0;
i < nelems;
i++)
4970 my_extra->partcollid[0],
#define PG_GETARG_ARRAYTYPE_P(n)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
static Datum values[MAXATTR]
static void cleanup(void)
#define TextDatumGetCString(d)
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
Datum datumCopy(Datum value, bool typByVal, int typLen)
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
elog(ERROR, "%s: %s", p2, msg)
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
bool ExecCheck(ExprState *state, ExprContext *econtext)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
EState * CreateExecutorState(void)
void FreeExecutorState(EState *estate)
#define GetPerTupleExprContext(estate)
#define ResetExprContext(econtext)
#define GetPerTupleMemoryContext(estate)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#define PG_GETARG_DATUM(n)
#define PG_GETARG_INT32(n)
#define PG_RETURN_BOOL(x)
static uint64 hash_combine64(uint64 a, uint64 b)
#define HeapTupleIsValid(tuple)
if(TABLE==NULL||TABLE_index==NULL)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
void list_free(List *list)
#define AccessExclusiveLock
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
RegProcedure get_opcode(Oid opno)
char * get_rel_name(Oid relid)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
Oid get_array_type(Oid typid)
#define type_is_array(typid)
Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)
RelabelType * makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Expr * make_ands_explicit(List *andclauses)
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Node * makeBoolConst(bool value, bool isnull)
void pfree(void *pointer)
void * palloc0(Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
#define CHECK_FOR_INTERRUPTS()
void fix_opfuncids(Node *node)
#define IsA(nodeptr, _type_)
#define IS_OUTER_JOIN(jointype)
#define castNode(_type_, nodeptr)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool IsBinaryCoercible(Oid srctype, Oid targettype)
int parser_errposition(ParseState *pstate, int location)
@ PARTITION_STRATEGY_HASH
@ PARTITION_STRATEGY_LIST
@ PARTITION_STRATEGY_RANGE
@ PARTITION_RANGE_DATUM_MAXVALUE
@ PARTITION_RANGE_DATUM_VALUE
@ PARTITION_RANGE_DATUM_MINVALUE
static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, PartitionRangeBound *probe, int32 *cmpval)
static int process_inner_partition(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, bool inner_has_default, int inner_index, int outer_default, JoinType jointype, int *next_index, int *default_index)
static void merge_default_partitions(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, bool inner_has_default, int outer_default, int inner_default, JoinType jointype, int *next_index, int *default_index)
static void init_partition_map(RelOptInfo *rel, PartitionMap *map)
static List * get_qual_for_list(Relation parent, PartitionBoundSpec *spec)
int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, Datum *rb_datums, PartitionRangeDatumKind *rb_kind, Datum *tuple_datums, int n_tuple_datums)
static int32 qsort_partition_rbound_cmp(const void *a, const void *b, void *arg)
static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, Datum *datums1, PartitionRangeDatumKind *kind1, bool lower1, PartitionRangeBound *b2)
struct PartitionListValue PartitionListValue
static PartitionBoundInfo create_list_bounds(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
static bool is_dummy_partition(RelOptInfo *rel, int part_index)
static PartitionBoundInfo merge_range_bounds(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
struct PartitionMap PartitionMap
bool partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, PartitionBoundInfo b1, PartitionBoundInfo b2)
PartitionBoundInfo partition_bounds_merge(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
static int merge_matching_partitions(PartitionMap *outer_map, PartitionMap *inner_map, int outer_index, int inner_index, int *next_index)
static List * get_qual_for_hash(Relation parent, PartitionBoundSpec *spec)
static void get_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, JoinType jointype, PartitionRangeBound *outer_lb, PartitionRangeBound *outer_ub, PartitionRangeBound *inner_lb, PartitionRangeBound *inner_ub, int lb_cmpval, int ub_cmpval, PartitionRangeBound *merged_lb, PartitionRangeBound *merged_ub)
#define compare_range_bounds(partnatts, partsupfunc, partcollations, bound1, bound2)
static int32 qsort_partition_hbound_cmp(const void *a, const void *b)
static void free_partition_map(PartitionMap *map)
static int get_non_null_list_datum_count(PartitionBoundSpec **boundspecs, int nparts)
void check_new_partition_bound(char *relname, Relation parent, PartitionBoundSpec *spec, ParseState *pstate)
static void fix_merged_indexes(PartitionMap *outer_map, PartitionMap *inner_map, int nmerged, List *merged_indexes)
List * get_qual_from_partbound(Relation parent, PartitionBoundSpec *spec)
static int merge_partition_with_dummy(PartitionMap *map, int index, int *next_index)
static Expr * make_partition_op_expr(PartitionKey key, int keynum, uint16 strategy, Expr *arg1, Expr *arg2)
PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
struct PartitionRangeBound PartitionRangeBound
static PartitionBoundInfo create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
bool partitions_are_ordered(PartitionBoundInfo boundinfo, Bitmapset *live_parts)
static List * get_qual_for_range(Relation parent, PartitionBoundSpec *spec, bool for_default)
static PartitionBoundInfo merge_list_bounds(FmgrInfo *partsupfunc, Oid *partcollation, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
static void generate_matching_part_pairs(RelOptInfo *outer_rel, RelOptInfo *inner_rel, PartitionMap *outer_map, PartitionMap *inner_map, int nmerged, List **outer_parts, List **inner_parts)
static void add_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, PartitionRangeBound *merged_lb, PartitionRangeBound *merged_ub, int merged_index, List **merged_datums, List **merged_kinds, List **merged_indexes)
uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, Datum *values, bool *isnull)
int partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, int nvalues, Datum *values, bool *is_equal)
Datum satisfies_hash_partition(PG_FUNCTION_ARGS)
static PartitionRangeBound * make_one_partition_rbound(PartitionKey key, int index, List *datums, bool lower)
int partition_hash_bsearch(PartitionBoundInfo boundinfo, int modulus, int remainder)
static void get_range_key_properties(PartitionKey key, int keynum, PartitionRangeDatum *ldatum, PartitionRangeDatum *udatum, ListCell **partexprs_item, Expr **keyCol, Const **lower_val, Const **upper_val)
static int32 partition_hbound_cmp(int modulus1, int remainder1, int modulus2, int remainder2)
static PartitionBoundInfo create_range_bounds(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
static int32 qsort_partition_list_value_cmp(const void *a, const void *b, void *arg)
static PartitionBoundInfo build_merged_partition_bounds(char strategy, List *merged_datums, List *merged_kinds, List *merged_indexes, int null_index, int default_index)
int get_hash_partition_greatest_modulus(PartitionBoundInfo bound)
static Oid get_partition_operator(PartitionKey key, int col, StrategyNumber strategy, bool *need_relabel)
struct PartitionHashBound PartitionHashBound
static bool compare_range_partitions(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, PartitionRangeBound *outer_lb, PartitionRangeBound *outer_ub, PartitionRangeBound *inner_lb, PartitionRangeBound *inner_ub, int *lb_cmpval, int *ub_cmpval)
static int get_range_partition(RelOptInfo *rel, PartitionBoundInfo bi, int *lb_pos, PartitionRangeBound *lb, PartitionRangeBound *ub)
static void merge_null_partitions(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_null, bool inner_has_null, int outer_null, int inner_null, JoinType jointype, int *next_index, int *null_index)
void check_default_partition_contents(Relation parent, Relation default_rel, PartitionBoundSpec *new_spec)
static int get_range_partition_internal(PartitionBoundInfo bi, int *lb_pos, PartitionRangeBound *lb, PartitionRangeBound *ub)
static List * get_range_nulltest(PartitionKey key)
static int process_outer_partition(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, bool inner_has_default, int outer_index, int inner_default, JoinType jointype, int *next_index, int *default_index)
int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, Datum value, bool *is_equal)
PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src, PartitionKey key)
#define partition_bound_has_default(bi)
#define partition_bound_accepts_nulls(bi)
PartitionKey RelationGetPartitionKey(Relation rel)
struct PartitionKeyData * PartitionKey
struct PartitionBoundInfoData * PartitionBoundInfo
PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached)
List * map_partition_varattnos(List *expr, int fromrel_varno, Relation to_rel, Relation from_rel)
List * get_proposed_default_constraint(List *new_part_constraints)
#define HASH_PARTITION_SEED
#define PARTITION_MAX_KEYS
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define list_make1_oid(x1)
static ListCell * list_head(const List *l)
#define list_make3(x1, x2, x3)
#define for_both_cell(cell1, list1, initcell1, cell2, list2, initcell2)
static void * list_nth(const List *list, int n)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define qsort(a, b, c, d)
static uint64 DatumGetUInt64(Datum X)
static bool DatumGetBool(Datum X)
static Datum UInt64GetDatum(uint64 X)
static Datum ObjectIdGetDatum(Oid X)
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
void * stringToNode(const char *str)
static unsigned hash(unsigned *uv, int n)
#define RelationGetRelid(relation)
#define RelationGetRelationName(relation)
int errtable(Relation rel)
char * get_range_partbound_string(List *bound_datums)
Snapshot GetLatestSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
#define BTGreaterStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
MemoryContext es_query_cxt
TupleTableSlot * ecxt_scantuple
NullTestType nulltesttype
PartitionRangeDatumKind ** kind
PartitionStrategy strategy
Bitmapset * interleaved_parts
PartitionBoundInfo boundinfo
PartitionRangeDatumKind * kind
PartitionRangeDatumKind kind
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key)
static void table_endscan(TableScanDesc scan)
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
bool PartConstraintImpliedByRelConstraint(Relation scanrel, List *partConstraint)