Esempio n. 1
0
datum_t gist_point_consistent(PG_FUNC_ARGS)
{
	struct gist_entry *entry = (struct gist_entry*) ARG_POINTER(0);
	strat_nr_t strategy = (strat_nr_t) ARG_UINT16(2);
	bool *recheck = (bool*) ARG_POINTER(4);
	bool result;
	strat_nr_t strategyGroup = strategy / GeoStrategyNumberOffset;

	switch (strategyGroup) {
	case PointStrategyNumberGroup:
		result = gist_point_consistent_internal(
			strategy % GeoStrategyNumberOffset,
			GIST_LEAF(entry),
			D_TO_BOX_P(entry->key),
			ARG_POINT_P(1));
		*recheck = false;
		break;

	case BoxStrategyNumberGroup:
		result = D_TO_BOOL(DIRECT_FC5(
			gist_box_consistent,
			PTR_TO_D(entry),
			ARG_DATUM(1),
			INT16_TO_D(RTOverlapStrategyNumber),
			0,
			PTR_TO_D(recheck)));
		break;

	case PolygonStrategyNumberGroup: {
		POLYGON *query = ARG_POLYGON_P(1);

		result = D_TO_BOOL(DIRECT_FC5(
			gist_poly_consistent,
			PTR_TO_D(entry),
			POLYGON_P_TO_D(query),
			INT16_TO_D(RTOverlapStrategyNumber),
			0,
			PTR_TO_D(recheck)));

		if (GIST_LEAF(entry) && result) {
			/*
			 * We are on leaf page and quick check shows overlapping
			 * of polygon's bounding box and point
			 */
			BOX *box;

			box = D_TO_BOX_P(entry->key);
			ASSERT(box->high.x == box->low.x && box->high.y == box->low.y);

			result = D_TO_BOOL(DIRECT_FC2(
				poly_contain_pt,
				POLYGON_P_TO_D(query),
				POINT_P_TO_D(&box->high)));
			*recheck = false;
			}
		}
		break;

	case CircleStrategyNumberGroup: {
		CIRCLE *query = ARG_CIRCLE_P(1);

		result = D_TO_BOOL(DIRECT_FC5(
			gist_circle_consistent,
			PTR_TO_D(entry),
			CIRCLE_P_TO_D(query),
			INT16_TO_D(RTOverlapStrategyNumber),
			0,
			PTR_TO_D(recheck)));

		if (GIST_LEAF(entry) && result) {
			/*
			 * We are on leaf page and quick check shows overlapping
			 * of polygon's bounding box and point
			 */
			BOX *box;

			box = D_TO_BOX_P(entry->key);
			ASSERT(box->high.x == box->low.x && box->high.y == box->low.y);

			result = D_TO_BOOL(DIRECT_FC2(
				circle_contain_pt,
				CIRCLE_P_TO_D(query),
				POINT_P_TO_D(&box->high)));
			*recheck = false;
			}
		}
		break;

	default:
		elog(ERROR, "unknown strategy number: %d", strategy);
		result = false;	/* keep compiler quiet */
	}

	RET_BOOL(result);
}
Esempio n. 2
0
Datum
gist_point_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	bool		result;
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
	StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;

	switch (strategyGroup)
	{
		case PointStrategyNumberGroup:
			result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset,
													GIST_LEAF(entry),
													DatumGetBoxP(entry->key),
													PG_GETARG_POINT_P(1));
			*recheck = false;
			break;
		case BoxStrategyNumberGroup:
			result = DatumGetBool(DirectFunctionCall5(
													  gist_box_consistent,
													  PointerGetDatum(entry),
													  PG_GETARG_DATUM(1),
									  Int16GetDatum(RTOverlapStrategyNumber),
											   0, PointerGetDatum(recheck)));
			break;
		case PolygonStrategyNumberGroup:
			{
				POLYGON    *query = PG_GETARG_POLYGON_P(1);

				result = DatumGetBool(DirectFunctionCall5(
														gist_poly_consistent,
													  PointerGetDatum(entry),
													 PolygonPGetDatum(query),
									  Int16GetDatum(RTOverlapStrategyNumber),
											   0, PointerGetDatum(recheck)));

				if (GIST_LEAF(entry) && result)
				{
					/*
					 * We are on leaf page and quick check shows overlapping
					 * of polygon's bounding box and point
					 */
					BOX		   *box = DatumGetBoxP(entry->key);

					Assert(box->high.x == box->low.x
						   && box->high.y == box->low.y);
					result = DatumGetBool(DirectFunctionCall2(
															  poly_contain_pt,
													 PolygonPGetDatum(query),
												PointPGetDatum(&box->high)));
					*recheck = false;
				}
			}
			break;
		case CircleStrategyNumberGroup:
			{
				CIRCLE	   *query = PG_GETARG_CIRCLE_P(1);

				result = DatumGetBool(DirectFunctionCall5(
													  gist_circle_consistent,
													  PointerGetDatum(entry),
													  CirclePGetDatum(query),
									  Int16GetDatum(RTOverlapStrategyNumber),
											   0, PointerGetDatum(recheck)));

				if (GIST_LEAF(entry) && result)
				{
					/*
					 * We are on leaf page and quick check shows overlapping
					 * of polygon's bounding box and point
					 */
					BOX		   *box = DatumGetBoxP(entry->key);

					Assert(box->high.x == box->low.x
						   && box->high.y == box->low.y);
					result = DatumGetBool(DirectFunctionCall2(
														   circle_contain_pt,
													  CirclePGetDatum(query),
												PointPGetDatum(&box->high)));
					*recheck = false;
				}
			}
			break;
		default:
			result = false;		/* silence compiler warning */
			elog(ERROR, "unknown strategy number: %d", strategy);
	}

	PG_RETURN_BOOL(result);
}
Esempio n. 3
0
Datum
gist_point_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
	bool		result;
	StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;

	switch (strategyGroup)
	{
		case PointStrategyNumberGroup:
			result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset,
													GIST_LEAF(entry),
													DatumGetBoxP(entry->key),
													PG_GETARG_POINT_P(1));
			*recheck = false;
			break;
		case BoxStrategyNumberGroup:
			{
				/*
				 * The only operator___ in this group is point <@ box (on_pb), so
				 * we needn't examine strategy again.
				 *
				 * For historical reasons, on_pb uses exact rather than fuzzy
				 * comparisons.  We could use box_overlap when at an internal
				 * page, but that would lead to possibly visiting child pages
				 * uselessly, because box_overlap uses fuzzy comparisons.
				 * Instead we write a non-fuzzy overlap test.  The same code
				 * will also serve for leaf-page tests, since leaf keys have
				 * high == low.
				 */
				BOX		   *query,
						   *key;

				query = PG_GETARG_BOX_P(1);
				key = DatumGetBoxP(entry->key);

				result = (key->high.x >= query->low.x &&
						  key->low.x <= query->high.x &&
						  key->high.y >= query->low.y &&
						  key->low.y <= query->high.y);
				*recheck = false;
			}
			break;
		case PolygonStrategyNumberGroup:
			{
				POLYGON    *query = PG_GETARG_POLYGON_P(1);

				result = DatumGetBool(DirectFunctionCall5(
														gist_poly_consistent,
													  PointerGetDatum(entry),
													 PolygonPGetDatum(query),
									  Int16GetDatum(RTOverlapStrategyNumber),
											   0, PointerGetDatum(recheck)));

				if (GIST_LEAF(entry) && result)
				{
					/*
					 * We are on leaf page and quick check shows overlapping
					 * of polygon's bounding box and point
					 */
					BOX		   *box = DatumGetBoxP(entry->key);

					Assert(box->high.x == box->low.x
						   && box->high.y == box->low.y);
					result = DatumGetBool(DirectFunctionCall2(
															  poly_contain_pt,
													 PolygonPGetDatum(query),
												PointPGetDatum(&box->high)));
					*recheck = false;
				}
			}
			break;
		case CircleStrategyNumberGroup:
			{
				CIRCLE	   *query = PG_GETARG_CIRCLE_P(1);

				result = DatumGetBool(DirectFunctionCall5(
													  gist_circle_consistent,
													  PointerGetDatum(entry),
													  CirclePGetDatum(query),
									  Int16GetDatum(RTOverlapStrategyNumber),
											   0, PointerGetDatum(recheck)));

				if (GIST_LEAF(entry) && result)
				{
					/*
					 * We are on leaf page and quick check shows overlapping
					 * of polygon's bounding box and point
					 */
					BOX		   *box = DatumGetBoxP(entry->key);

					Assert(box->high.x == box->low.x
						   && box->high.y == box->low.y);
					result = DatumGetBool(DirectFunctionCall2(
														   circle_contain_pt,
													  CirclePGetDatum(query),
												PointPGetDatum(&box->high)));
					*recheck = false;
				}
			}
			break;
		default:
			elog(ERROR, "unrecognized strategy number: %d", strategy);
			result = false;		/* keep compiler quiet */
			break;
	}

	PG_RETURN_BOOL(result);
}