|
6 | 6 | #include <utils/rel.h>
|
7 | 7 | #include <catalog/indexing.h>
|
8 | 8 | #include <funcapi.h>
|
| 9 | +#include <utils/lsyscache.h> |
| 10 | +#include <catalog/pg_opfamily.h> |
| 11 | +#include <catalog/pg_type.h> |
9 | 12 |
|
10 | 13 | #include "catalog.h"
|
11 | 14 | #include "dimension_slice.h"
|
@@ -166,6 +169,84 @@ dimension_slice_scan_limit(int32 dimension_id, int64 coordinate, int limit)
|
166 | 169 | return dimension_vec_sort(&slices);
|
167 | 170 | }
|
168 | 171 |
|
| 172 | +/* |
| 173 | + * Look for all ranges where value > lower_bound and value < upper_bound |
| 174 | + * |
| 175 | + */ |
| 176 | +DimensionVec * |
| 177 | +dimension_slice_scan_range_limit(int32 dimension_id, StrategyNumber start_strategy, int64 start_value, StrategyNumber end_strategy, int64 end_value, int limit) |
| 178 | +{ |
| 179 | + ScanKeyData scankey[3]; |
| 180 | + DimensionVec *slices = dimension_vec_create(limit > 0 ? limit : DIMENSION_VEC_DEFAULT_SIZE); |
| 181 | + int nkeys = 1; |
| 182 | + |
| 183 | + /* |
| 184 | + * Perform an index scan for slices matching the dimension's ID and which |
| 185 | + * enclose the coordinate. |
| 186 | + */ |
| 187 | + ScanKeyInit(&scankey[0], Anum_dimension_slice_dimension_id_range_start_range_end_idx_dimension_id, |
| 188 | + BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(dimension_id)); |
| 189 | + if (start_strategy != InvalidStrategy) |
| 190 | + { |
| 191 | + Oid opno = get_opfamily_member(INTEGER_BTREE_FAM_OID, INT8OID, INT8OID, start_strategy); |
| 192 | + Oid proc = get_opcode(opno); |
| 193 | + |
| 194 | + Assert(OidIsValid(proc)); |
| 195 | + |
| 196 | + ScanKeyInit(&scankey[nkeys++], |
| 197 | + Anum_dimension_slice_dimension_id_range_start_range_end_idx_range_start, |
| 198 | + start_strategy, |
| 199 | + proc, |
| 200 | + Int64GetDatum(start_value)); |
| 201 | + } |
| 202 | + if (end_strategy != InvalidStrategy) |
| 203 | + { |
| 204 | + Oid opno = get_opfamily_member(INTEGER_BTREE_FAM_OID, INT8OID, INT8OID, end_strategy); |
| 205 | + Oid proc = get_opcode(opno); |
| 206 | + |
| 207 | + Assert(OidIsValid(proc)); |
| 208 | + |
| 209 | + /* |
| 210 | + * range_end is stored as exclusive, so add 1 to the value being |
| 211 | + * searched. Also avoid overflow |
| 212 | + */ |
| 213 | + if (end_value != PG_INT64_MAX) |
| 214 | + { |
| 215 | + end_value++; |
| 216 | + |
| 217 | + /* |
| 218 | + * If getting as input INT64_MAX-1, need to remap the incremented |
| 219 | + * value back to INT64_MAX-1 |
| 220 | + */ |
| 221 | + end_value = REMAP_LAST_COORDINATE(end_value); |
| 222 | + } |
| 223 | + else |
| 224 | + { |
| 225 | + /* |
| 226 | + * The point with INT64_MAX gets mapped to INT64_MAX-1 so |
| 227 | + * incrementing that gets you to INT_64MAX |
| 228 | + */ |
| 229 | + end_value = PG_INT64_MAX; |
| 230 | + } |
| 231 | + |
| 232 | + ScanKeyInit(&scankey[nkeys++], |
| 233 | + Anum_dimension_slice_dimension_id_range_start_range_end_idx_range_end, |
| 234 | + end_strategy, |
| 235 | + proc, |
| 236 | + Int64GetDatum(end_value)); |
| 237 | + } |
| 238 | + |
| 239 | + dimension_slice_scan_limit_internal(DIMENSION_SLICE_DIMENSION_ID_RANGE_START_RANGE_END_IDX, |
| 240 | + scankey, |
| 241 | + nkeys, |
| 242 | + dimension_vec_tuple_found, |
| 243 | + &slices, |
| 244 | + limit, |
| 245 | + AccessShareLock); |
| 246 | + |
| 247 | + return dimension_vec_sort(&slices); |
| 248 | +} |
| 249 | + |
169 | 250 | /*
|
170 | 251 | * Scan for slices that collide/overlap with the given range.
|
171 | 252 | *
|
@@ -408,13 +489,15 @@ dimension_slice_cut(DimensionSlice *to_cut, DimensionSlice *other, int64 coord)
|
408 | 489 | {
|
409 | 490 | /* Cut "before" the coordinate */
|
410 | 491 | to_cut->fd.range_start = other->fd.range_end;
|
| 492 | + |
411 | 493 | return true;
|
412 | 494 | }
|
413 | 495 | else if (other->fd.range_start > coord &&
|
414 | 496 | other->fd.range_start < to_cut->fd.range_end)
|
415 | 497 | {
|
416 | 498 | /* Cut "after" the coordinate */
|
417 | 499 | to_cut->fd.range_end = other->fd.range_start;
|
| 500 | + |
418 | 501 | return true;
|
419 | 502 | }
|
420 | 503 |
|
|
0 commit comments