PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ gserialized_spgist_inner_consistent_2d()

PGDLLEXPORT Datum gserialized_spgist_inner_consistent_2d ( PG_FUNCTION_ARGS  )

Definition at line 406 of file gserialized_spgist_2d.c.

407 {
408  spgInnerConsistentIn *in = (spgInnerConsistentIn *)PG_GETARG_POINTER(0);
409  spgInnerConsistentOut *out = (spgInnerConsistentOut *)PG_GETARG_POINTER(1);
410  int i;
411  MemoryContext old_ctx;
412  RectBox *rect_box;
413  uint8 quadrant;
414  BOX2DF *centroid;
415 
416  if (in->allTheSame)
417  {
418  /* Report that all nodes should be visited */
419  out->nNodes = in->nNodes;
420  out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes);
421  for (i = 0; i < in->nNodes; i++)
422  out->nodeNumbers[i] = i;
423 
424  PG_RETURN_VOID();
425  }
426 
427  /*
428  * We are saving the traversal value or initialize it an unbounded one, if
429  * we have just begun to walk the tree.
430  */
431  if (in->traversalValue)
432  rect_box = in->traversalValue;
433  else
434  rect_box = initRectBox();
435 
436  centroid = (BOX2DF *)DatumGetPointer(in->prefixDatum);
437 
438  /* Allocate enough memory for nodes */
439  out->nNodes = 0;
440  out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes);
441  out->traversalValues = (void **)palloc(sizeof(void *) * in->nNodes);
442 
443  /*
444  * We switch memory context, because we want to allocate memory for new
445  * traversal values (next_rect_box) and pass these pieces of memory to
446  * further call of this function.
447  */
448  old_ctx = MemoryContextSwitchTo(in->traversalMemoryContext);
449 
450  for (quadrant = 0; quadrant < in->nNodes; quadrant++)
451  {
452  RectBox *next_rect_box = nextRectBox(rect_box, centroid, quadrant);
453  bool flag = true;
454 
455  for (i = 0; i < in->nkeys; i++)
456  {
457  StrategyNumber strategy = in->scankeys[i].sk_strategy;
458 
459  Datum query = in->scankeys[i].sk_argument;
460  BOX2DF query_gbox_index;
461 
462  /* Quick sanity check on query argument. */
463  if (DatumGetPointer(query) == NULL)
464  {
465  POSTGIS_DEBUG(4, "[SPGIST] null query pointer (!?!), returning false");
466  PG_RETURN_BOOL(false); /* NULL query! This is screwy! */
467  }
468 
469  if (gserialized_datum_get_box2df_p(query, &query_gbox_index) == LW_FAILURE)
470  {
471  POSTGIS_DEBUG(4, "[SPGIST] null query_gbox_index!");
472  PG_RETURN_BOOL(false);
473  }
474 
475  switch (strategy)
476  {
477  case RTOverlapStrategyNumber:
478  case RTContainedByStrategyNumber:
479  case RTOldContainedByStrategyNumber:
480  flag = overlap4D(next_rect_box, &query_gbox_index);
481  break;
482 
483  case RTContainsStrategyNumber:
484  case RTSameStrategyNumber:
485  flag = contain4D(next_rect_box, &query_gbox_index);
486  break;
487 
488  case RTLeftStrategyNumber:
489  flag = !overRight4D(next_rect_box, &query_gbox_index);
490  break;
491 
492  case RTOverLeftStrategyNumber:
493  flag = !right4D(next_rect_box, &query_gbox_index);
494  break;
495 
496  case RTRightStrategyNumber:
497  flag = !overLeft4D(next_rect_box, &query_gbox_index);
498  break;
499 
500  case RTOverRightStrategyNumber:
501  flag = !left4D(next_rect_box, &query_gbox_index);
502  break;
503 
504  case RTAboveStrategyNumber:
505  flag = !overBelow4D(next_rect_box, &query_gbox_index);
506  break;
507 
508  case RTOverAboveStrategyNumber:
509  flag = !below4D(next_rect_box, &query_gbox_index);
510  break;
511 
512  case RTBelowStrategyNumber:
513  flag = !overAbove4D(next_rect_box, &query_gbox_index);
514  break;
515 
516  case RTOverBelowStrategyNumber:
517  flag = !above4D(next_rect_box, &query_gbox_index);
518  break;
519 
520  default:
521  elog(ERROR, "unrecognized strategy: %d", strategy);
522  }
523 
524  /* If any check is failed, we have found our answer. */
525  if (!flag)
526  break;
527  }
528 
529  if (flag)
530  {
531  out->traversalValues[out->nNodes] = next_rect_box;
532  out->nodeNumbers[out->nNodes] = quadrant;
533  out->nNodes++;
534  }
535  else
536  {
537  /*
538  * If this node is not selected, we don't need to keep the next
539  * traversal value in the memory context.
540  */
541  pfree(next_rect_box);
542  }
543  }
544 
545  /* Switch after */
546  MemoryContextSwitchTo(old_ctx);
547 
548  PG_RETURN_VOID();
549 }
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
Peak into a GSERIALIZED datum to find the bounding box.
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 * nextRectBox(RectBox *rect_box, BOX2DF *centroid, uint8 quadrant)
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)
#define LW_FAILURE
Definition: liblwgeom.h:79
Datum centroid(PG_FUNCTION_ARGS)

References above4D(), below4D(), centroid(), contain4D(), gserialized_datum_get_box2df_p(), initRectBox(), left4D(), LW_FAILURE, nextRectBox(), overAbove4D(), overBelow4D(), overlap4D(), overLeft4D(), overRight4D(), and right4D().

Here is the call graph for this function: