409{
410 spgInnerConsistentIn *in = (spgInnerConsistentIn *)PG_GETARG_POINTER(0);
411 spgInnerConsistentOut *out = (spgInnerConsistentOut *)PG_GETARG_POINTER(1);
412 int i;
413 MemoryContext old_ctx;
415 uint8 quadrant;
417
418 if (in->allTheSame)
419 {
420
421 out->nNodes = in->nNodes;
422 out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes);
423 for (i = 0; i < in->nNodes; i++)
424 out->nodeNumbers[i] = i;
425
426 PG_RETURN_VOID();
427 }
428
429
430
431
432
433 if (in->traversalValue)
434 rect_box = in->traversalValue;
435 else
437
438 centroid = (BOX2DF *)DatumGetPointer(in->prefixDatum);
439
440
441 out->nNodes = 0;
442 out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes);
443 out->traversalValues = (void **)palloc(sizeof(void *) * in->nNodes);
444
445
446
447
448
449
450 old_ctx = MemoryContextSwitchTo(in->traversalMemoryContext);
451
452 for (quadrant = 0; quadrant < (uint8)in->nNodes; quadrant++)
453 {
455 bool flag = true;
456
457 for (i = 0; i < in->nkeys; i++)
458 {
459 StrategyNumber strategy = in->scankeys[i].sk_strategy;
460
461 Datum query = in->scankeys[i].sk_argument;
462 BOX2DF query_gbox_index;
463
464
465 if (DatumGetPointer(query) == NULL)
466 {
467 POSTGIS_DEBUG(4, "[SPGIST] null query pointer (!?!), returning false");
468 PG_RETURN_BOOL(false);
469 }
470
472 {
473 POSTGIS_DEBUG(4, "[SPGIST] null query_gbox_index!");
474 PG_RETURN_BOOL(false);
475 }
476
477 switch (strategy)
478 {
479 case RTOverlapStrategyNumber:
480 case RTContainedByStrategyNumber:
481 case RTOldContainedByStrategyNumber:
482 flag =
overlap4D(next_rect_box, &query_gbox_index);
483 break;
484
485 case RTContainsStrategyNumber:
486 case RTSameStrategyNumber:
487 flag =
contain4D(next_rect_box, &query_gbox_index);
488 break;
489
490 case RTLeftStrategyNumber:
491 flag = !
overRight4D(next_rect_box, &query_gbox_index);
492 break;
493
494 case RTOverLeftStrategyNumber:
495 flag = !
right4D(next_rect_box, &query_gbox_index);
496 break;
497
498 case RTRightStrategyNumber:
499 flag = !
overLeft4D(next_rect_box, &query_gbox_index);
500 break;
501
502 case RTOverRightStrategyNumber:
503 flag = !
left4D(next_rect_box, &query_gbox_index);
504 break;
505
506 case RTAboveStrategyNumber:
507 flag = !
overBelow4D(next_rect_box, &query_gbox_index);
508 break;
509
510 case RTOverAboveStrategyNumber:
511 flag = !
below4D(next_rect_box, &query_gbox_index);
512 break;
513
514 case RTBelowStrategyNumber:
515 flag = !
overAbove4D(next_rect_box, &query_gbox_index);
516 break;
517
518 case RTOverBelowStrategyNumber:
519 flag = !
above4D(next_rect_box, &query_gbox_index);
520 break;
521
522 default:
523 elog(ERROR, "unrecognized strategy: %d", strategy);
524 }
525
526
527 if (!flag)
528 break;
529 }
530
531 if (flag)
532 {
533 out->traversalValues[out->nNodes] = next_rect_box;
534 out->nodeNumbers[out->nNodes] = quadrant;
535 out->nNodes++;
536 }
537 else
538 {
539
540
541
542
543 pfree(next_rect_box);
544 }
545 }
546
547
548 MemoryContextSwitchTo(old_ctx);
549
550 PG_RETURN_VOID();
551}
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
static RectBox * nextRectBox(RectBox *rect_box, BOX2DF *centroid, uint8 quadrant)
static bool right4D(RectBox *rect_box, BOX2DF *query)
static bool overRight4D(RectBox *rect_box, BOX2DF *query)
static bool overlap4D(RectBox *rect_box, BOX2DF *query)
static bool overAbove4D(RectBox *rect_box, BOX2DF *query)
static bool above4D(RectBox *rect_box, BOX2DF *query)
static RectBox * initRectBox(void)
static bool contain4D(RectBox *rect_box, BOX2DF *query)
static bool left4D(RectBox *rect_box, BOX2DF *query)
static bool below4D(RectBox *rect_box, BOX2DF *query)
static bool overBelow4D(RectBox *rect_box, BOX2DF *query)
static bool overLeft4D(RectBox *rect_box, BOX2DF *query)
Datum centroid(PG_FUNCTION_ARGS)