PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ gserialized_spgist_inner_consistent_2d()

PGDLLEXPORT Datum gserialized_spgist_inner_consistent_2d ( PG_FUNCTION_ARGS  )

Definition at line 408 of file gserialized_spgist_2d.c.

409 {
410  spgInnerConsistentIn *in = (spgInnerConsistentIn *)PG_GETARG_POINTER(0);
411  spgInnerConsistentOut *out = (spgInnerConsistentOut *)PG_GETARG_POINTER(1);
412  int i;
413  MemoryContext old_ctx;
414  RectBox *rect_box;
415  uint8 quadrant;
416  BOX2DF *centroid;
417 
418  if (in->allTheSame)
419  {
420  /* Report that all nodes should be visited */
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  * We are saving the traversal value or initialize it an unbounded one, if
431  * we have just begun to walk the tree.
432  */
433  if (in->traversalValue)
434  rect_box = in->traversalValue;
435  else
436  rect_box = initRectBox();
437 
438  centroid = (BOX2DF *)DatumGetPointer(in->prefixDatum);
439 
440  /* Allocate enough memory for nodes */
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  * We switch memory context, because we want to allocate memory for new
447  * traversal values (next_rect_box) and pass these pieces of memory to
448  * further call of this function.
449  */
450  old_ctx = MemoryContextSwitchTo(in->traversalMemoryContext);
451 
452  for (quadrant = 0; quadrant < in->nNodes; quadrant++)
453  {
454  RectBox *next_rect_box = nextRectBox(rect_box, centroid, quadrant);
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  /* Quick sanity check on query argument. */
465  if (DatumGetPointer(query) == NULL)
466  {
467  POSTGIS_DEBUG(4, "[SPGIST] null query pointer (!?!), returning false");
468  PG_RETURN_BOOL(false); /* NULL query! This is screwy! */
469  }
470 
471  if (gserialized_datum_get_box2df_p(query, &query_gbox_index) == LW_FAILURE)
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  /* If any check is failed, we have found our answer. */
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  * If this node is not selected, we don't need to keep the next
541  * traversal value in the memory context.
542  */
543  pfree(next_rect_box);
544  }
545  }
546 
547  /* Switch after */
548  MemoryContextSwitchTo(old_ctx);
549 
550  PG_RETURN_VOID();
551 }
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:110
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: