Esempio n. 1
0
Datum
gbt_int8_consistent(MDB_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) MDB_GETARG_POINTER(0);
	int64		query = MDB_GETARG_INT64(1);
	StrategyNumber strategy = (StrategyNumber) MDB_GETARG_UINT16(2);

	/* Oid		subtype = MDB_GETARG_OID(3); */
	bool	   *recheck = (bool *) MDB_GETARG_POINTER(4);
	int64KEY   *kkk = (int64KEY *) DatumGetPointer(entry->key);
	GBT_NUMKEY_R key;

	/* All cases served by this function are exact */
	*recheck = false;

	key.lower = (GBT_NUMKEY *) &kkk->lower;
	key.upper = (GBT_NUMKEY *) &kkk->upper;

	MDB_RETURN_BOOL(
				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
		);
}
Esempio n. 2
0
Datum
gbt_ts_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	Timestamp	query = PG_GETARG_TIMESTAMP(1);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

	/* Oid		subtype = PG_GETARG_OID(3); */
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
	tsKEY	   *kkk = (tsKEY *) DatumGetPointer(entry->key);
	GBT_NUMKEY_R key;

	/* All cases served by this function are exact */
	*recheck = false;

	key.lower = (GBT_NUMKEY *) &kkk->lower;
	key.upper = (GBT_NUMKEY *) &kkk->upper;

	PG_RETURN_BOOL(
				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
		);
}
Esempio n. 3
0
/*
 * The GiST Consistent method for boxes
 *
 * Should return false if for all data items x below entry,
 * the predicate x op query must be FALSE, where op is the oper
 * corresponding to strategy in the pg_amop table.
 */
datum_t gist_box_consistent(PG_FUNC_ARGS)
{
	struct gist_entry* entry = (struct gist_entry *)ARG_POINTER(0);
	BOX* query = ARG_BOX_P(1);
	strat_nr_t strategy = (strat_nr_t) ARG_UINT16(2);

	/* oid_t                subtype = ARG_OID(3); */
	bool* recheck = (bool*) ARG_POINTER(4);

	/* All cases served by this function are exact */
	*recheck = false;
	if (D_TO_BOX_P(entry->key) == NULL || query == NULL)
		RET_BOOL(FALSE);

	/*
	 * if entry is not leaf, use rtree_internal_consistent, else use
	 * gist_box_leaf_consistent
	 */
	if (GIST_LEAF(entry))
		RET_BOOL(gist_box_leaf_consistent(D_TO_BOX_P(entry->key), query, strategy));
	else
		RET_BOOL(rtree_internal_consistent(D_TO_BOX_P(entry->key), query, strategy));
}
Esempio n. 4
0
File: gistproc.c Progetto: 50wu/gpdb
/*
 * The GiST Consistent method for boxes
 *
 * Should return false if for all data items x below entry,
 * the predicate x op query must be FALSE, where op is the oper
 * corresponding to strategy in the pg_amop table.
 */
Datum
gist_box_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	BOX		   *query = PG_GETARG_BOX_P(1);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

	if (DatumGetBoxP(entry->key) == NULL || query == NULL)
		PG_RETURN_BOOL(FALSE);

	/*
	 * if entry is not leaf, use rtree_internal_consistent, else use
	 * gist_box_leaf_consistent
	 */
	if (GIST_LEAF(entry))
		PG_RETURN_BOOL(gist_box_leaf_consistent(DatumGetBoxP(entry->key),
												query,
												strategy));
	else
		PG_RETURN_BOOL(rtree_internal_consistent(DatumGetBoxP(entry->key),
												 query,
												 strategy));
}
Esempio n. 5
0
Datum
gist_point_distance(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	double		distance;
	StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;

	switch (strategyGroup)
	{
		case PointStrategyNumberGroup:
			distance = computeDistance(GIST_LEAF(entry),
									   DatumGetBoxP(entry->key),
									   PG_GETARG_POINT_P(1));
			break;
		default:
			elog(ERROR, "unrecognized strategy number: %d", strategy);
			distance = 0.0;		/* keep compiler quiet */
			break;
	}

	PG_RETURN_FLOAT8(distance);
}
Esempio n. 6
0
Datum
gbt_timetz_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	TimeTzADT  *query = PG_GETARG_TIMETZADT_P(1);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

	timeKEY    *kkk = (timeKEY *) DatumGetPointer(entry->key);
	TimeADT		qqq;
	GBT_NUMKEY_R key;

#ifdef HAVE_INT64_TIMESTAMP
	qqq = query->time + (query->zone * INT64CONST(1000000));
#else
	qqq = (query->time + query->zone);
#endif

	key.lower = (GBT_NUMKEY *) & kkk->lower;
	key.upper = (GBT_NUMKEY *) & kkk->upper;

	PG_RETURN_BOOL(
				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
		);
}
Esempio n. 7
0
Datum
gbt_tstz_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	TimestampTz query = PG_GETARG_TIMESTAMPTZ(1);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

	/* Oid		subtype = PG_GETARG_OID(3); */
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
	char	   *kkk = (char *) DatumGetPointer(entry->key);
	GBT_NUMKEY_R key;
	Timestamp	qqq;

	/* All cases served by this function are exact */
	*recheck = false;

	key.lower = (GBT_NUMKEY *) &kkk[0];
	key.upper = (GBT_NUMKEY *) &kkk[MAXALIGN(tinfo.size)];
	qqq = tstz_to_ts_gmt(query);

	PG_RETURN_BOOL(
				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
		);
}
/*
** The GiST Consistent method for _intments
** Should return false if for all data items x below entry,
** the predicate x op query == FALSE, where op is the oper
** corresponding to strategy in the pg_amop table.
*/
Datum
g_int_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	ArrayType  *query = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(1));
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

	/* Oid		subtype = PG_GETARG_OID(3); */
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
	bool		retval;

	/* this is exact except for RTSameStrategyNumber */
	*recheck = (strategy == RTSameStrategyNumber);

	if (strategy == BooleanSearchStrategy)
	{
		retval = execconsistent((QUERYTYPE *) query,
								(ArrayType *) DatumGetPointer(entry->key),
								GIST_LEAF(entry));

		pfree(query);
		PG_RETURN_BOOL(retval);
	}

	/* sort query for fast search, key is already sorted */
	CHECKARRVALID(query);
	if (ARRISVOID(query))
	{
		pfree(query);
		PG_RETURN_BOOL(false);
	}
	PREPAREARR(query);

	switch (strategy)
	{
		case RTOverlapStrategyNumber:
			retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
									   query);
			break;
		case RTSameStrategyNumber:
			if (GIST_LEAF(entry))
				DirectFunctionCall3(
									g_int_same,
									entry->key,
									PointerGetDatum(query),
									PointerGetDatum(&retval)
					);
			else
				retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
											query);
			break;
		case RTContainsStrategyNumber:
		case RTOldContainsStrategyNumber:
			retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
										query);
			break;
		case RTContainedByStrategyNumber:
		case RTOldContainedByStrategyNumber:
			if (GIST_LEAF(entry))
				retval = inner_int_contains(query,
								  (ArrayType *) DatumGetPointer(entry->key));
			else
				retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
										   query);
			break;
		default:
			retval = FALSE;
	}
	pfree(query);
	PG_RETURN_BOOL(retval);
}
Esempio n. 9
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. 10
0
Datum
greaction_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);
  bytea *key = (bytea*)DatumGetPointer(entry->key);
  bytea *query;
  bool  res = true;

  fcinfo->flinfo->fn_extra = searchReactionCache(
						 fcinfo->flinfo->fn_extra,
						 fcinfo->flinfo->fn_mcxt,
						 PG_GETARG_DATUM(1),
						 NULL, NULL,&query);
  /*
  ** RDKitContains, RDKitContained, RDKitEquals require a recheck, but 
  ** it defaults to false, so that RDkitSmaller and RDKitGreater can reuse
  ** the RDKitContains, RDKitContained implementation.
  */
  *recheck = false;

  switch (strategy) {
  case RDKitContains:
    *recheck = true;
    /* fallthrough */
  case RDKitSmaller:
    if (!ISALLTRUE(key)) {
      int siglen = SIGLEN(key);

      if (siglen != SIGLEN(query)) {
            elog(ERROR, "All fingerprints should be the same length");
      }
      
      uint8 *k = (uint8 *)VARDATA(key);
      uint8 *q = (uint8 *)VARDATA(query);

      res = bitstringContains(siglen, k, q);
    }
    break;
  case RDKitContained:
    *recheck = true;
    /* fallthrough */
  case RDKitGreater:
    if (!ISALLTRUE(key)) {
      int siglen = SIGLEN(key);
     
      if (siglen != SIGLEN(query)) {
	elog(ERROR, "All fingerprints should be the same length");
      }
      
      uint8 *k = (uint8 *)VARDATA(key);
      uint8 *q = (uint8 *)VARDATA(query);

      if ( GIST_LEAF(entry) ) {
	res = bitstringContains(siglen, q, k);
      }
      else {
	/*
	 * Due to superimposed key on inner page we could only check
	 * overlapping
	 */
	res = bitstringIntersects(siglen, q, k);
      }
    }
    else if (GIST_LEAF(entry)) {
      res = bitstringAllTrue(SIGLEN(query), (uint8 *)VARDATA(query));
    }
    break;
  case RDKitEquals:
    *recheck = true;
    
    if (!ISALLTRUE(key)) {
      int siglen = SIGLEN(key);
      
      if (siglen != SIGLEN(query)) {
	elog(ERROR, "All fingerprints should be the same length");
      }

      uint8 *k = (uint8 *)VARDATA(key);
      uint8 *q = (uint8 *)VARDATA(query);
      
      res =
	bitstringContains(siglen, k, q)
	/* 
	** the original implementation also required the query to
	** contain the key, but (I think) this is only true on the 
	** leaves (FIXME?)
	*/
	&& bitstringContains(siglen, q, k)
	;
    }
    break;
  default:
    elog(ERROR,"Unknown strategy: %d", strategy);
  }
  
  PG_RETURN_BOOL(res);
}
Esempio n. 11
0
Datum
gmol_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);
  bytea                   *key = (bytea*)DatumGetPointer(entry->key);
  bytea                   *query;
  bool                    res = true;

  int siglen = SIGLEN(key);
  
  fcinfo->flinfo->fn_extra = searchMolCache(
                                            fcinfo->flinfo->fn_extra,
                                            fcinfo->flinfo->fn_mcxt,
                                            PG_GETARG_DATUM(1), 
                                            NULL, NULL,&query);

  /*
  ** recheck is required for all strategies
  */
  *recheck = true;
  
  switch (strategy) {
  case RDKitContains:
    if (!ISALLTRUE(key)) {
      if (siglen != SIGLEN(query)) {
	elog(ERROR, "All fingerprints should be the same length");
      }
      
      uint8 *k = (uint8 *)VARDATA(key);
      uint8 *q = (uint8 *)VARDATA(query);
      
      res = bitstringContains(siglen, k, q);
    }
    break;
  case RDKitContained:
    if (!ISALLTRUE(key)) {
      if (siglen != SIGLEN(query)) {
	elog(ERROR, "All fingerprints should be the same length");
      }
      
      uint8 *k = (uint8 *)VARDATA(key);
      uint8 *q = (uint8 *)VARDATA(query);
      
      if (GIST_LEAF(entry)) {
	res = bitstringContains(siglen, q, k);
      }
      else {
	/*
	 * Due to superimposed key on inner page we could only check
	 * overlapping
	 */
	res = bitstringIntersects(siglen, q, k);
      }
    } 
    else if (GIST_LEAF(entry)) {
      /* 
       * key is all true, it may be contained in query, iff query is also 
       * all true
       */
      res = bitstringAllTrue(siglen, (uint8 *)VARDATA(query));
    }
    break;
  case RDKitEquals:
    if (!ISALLTRUE(key)) {
      /*
      ** verify the necessary condition that key should contain the query
      ** (on leaf nodes, couldn't it also verify that query contains key?)
      */
      if (siglen != SIGLEN(query)) {
	elog(ERROR, "All fingerprints should be the same length");
      }
      
      uint8 *k = (uint8 *)VARDATA(key);
      uint8 *q = (uint8 *)VARDATA(query);
      
      res = bitstringContains(siglen, k, q);
    }
    break;
  default:
    elog(ERROR,"Unknown strategy: %d", strategy);
  }

  PG_RETURN_BOOL(res);
}
Esempio n. 12
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. 13
0
Datum
gbfp_distance(PG_FUNCTION_ARGS)
{
    GISTENTRY      *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    // bytea          *query = PG_GETARG_DATA_TYPE_P(1);
    StrategyNumber  strategy = (StrategyNumber) PG_GETARG_UINT16(2);
    bytea          *key = (bytea*)DatumGetPointer(entry->key);

    bytea          *query;
    double          nCommon, nCommonUp, nCommonDown, nQuery, distance;
    double          nKey = 0.0;

    fcinfo->flinfo->fn_extra = SearchBitmapFPCache(
                                                   fcinfo->flinfo->fn_extra,
                                                   fcinfo->flinfo->fn_mcxt,
                                                   PG_GETARG_DATUM(1),
                                                   NULL, NULL,&query);

    if (ISALLTRUE(query))
        elog(ERROR, "Query malformed");

    /*
    * Counts basic numbers, but don't count nKey on inner
    * page (see comments below)
    */
    nQuery = (double)sizebitvec(query);
    if (ISALLTRUE(key))
        {

        if (GIST_LEAF(entry)) nKey = (double)SIGLENBIT(query);

        nCommon = nQuery;
        }
    else
        {
        int i, cnt = 0;
        unsigned char *pk = (unsigned char*)VARDATA(key),
            *pq = (unsigned char*)VARDATA(query);

        if (SIGLEN(key) != SIGLEN(query))
            elog(ERROR, "All fingerprints should be the same length");

#ifndef USE_BUILTIN_POPCOUNT
        for(i=0;i<SIGLEN(key);i++)
            cnt += number_of_ones[ pk[i] & pq[i] ];
#else
        unsigned eidx=SIGLEN(key)/sizeof(unsigned int);
        for(i=0;i<SIGLEN(key)/sizeof(unsigned int);++i){
          cnt += __builtin_popcount(((unsigned int *)pk)[i] & ((unsigned int *)pq)[i]);
        }
        for(i=eidx*sizeof(unsigned);i<SIGLEN(key);++i){
          cnt += number_of_ones[ pk[i] & pq[i] ];
        }
#endif        

        nCommon = (double)cnt;
        if (GIST_LEAF(entry))
            nKey = (double)sizebitvec(key);
        }

    nCommonUp = nCommon;
    nCommonDown = nCommon;

    switch(strategy)
    {
        case RDKitOrderByTanimotoStrategy:
        /*
        * Nsame / (Na + Nb - Nsame)
        */
        if (GIST_LEAF(entry))
        {
            distance = nCommonUp / (nKey + nQuery - nCommonUp);
        }

        else
        {
            distance = nCommonUp / nQuery;
        }

        break;

        case RDKitOrderByDiceStrategy:
        /*
        * 2 * Nsame / (Na + Nb)
        */
        if (GIST_LEAF(entry))
        {
            distance = 2.0 * nCommonUp / (nKey + nQuery);
        }

        else
        {
            distance =  2.0 * nCommonUp / (nCommonDown + nQuery);
        }

        break;

        default:
        elog(ERROR,"Unknown strategy: %d", strategy);
    }

    PG_RETURN_FLOAT8(1.0 - distance);
}
Esempio n. 14
0
Datum
gmol_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);
  bytea                   *key = (bytea*)DatumGetPointer(entry->key);
  bytea                   *query;
  bool                    res = true;

  fcinfo->flinfo->fn_extra = SearchMolCache(
                                            fcinfo->flinfo->fn_extra,
                                            fcinfo->flinfo->fn_mcxt,
                                            PG_GETARG_DATUM(1), 
                                            NULL, NULL,&query);

  switch(strategy)
    {
    case RDKitContains:
      *recheck = true;

      if (!ISALLTRUE(key))
        {
          int i;
          unsigned char   *k = (unsigned char*)VARDATA(key),
            *q = (unsigned char*)VARDATA(query);

          if (SIGLEN(key) != SIGLEN(query))
            elog(ERROR, "All fingerprints should be the same length");

          for(i=0; res && i<SIGLEN(key); i++)
            if ( (k[i] & q[i]) != q[i])
              res = false;
        }
      break;
    case RDKitContained:
      *recheck = true;

      if (!ISALLTRUE(key))
        {
          int i;
          unsigned char   *k = (unsigned char*)VARDATA(key),
            *q = (unsigned char*)VARDATA(query);

          if (SIGLEN(key) != SIGLEN(query))
            elog(ERROR, "All fingerprints should be the same length");

          if ( GIST_LEAF(entry) )
            {
              for(i=0; res && i<SIGLEN(key); i++)
                if ( (k[i] & q[i]) != k[i])
                  res = false;
            }
          else
            {
              /*
               * Due to superimposed key on inner page we could only check
               * overlapping
               */
              res = false;
              for(i=0; res == false && i<SIGLEN(key); i++)
                if ( k[i] & q[i] )
                  res = true;
            }
        } 
      else if (GIST_LEAF(entry))
        {
          int i;
          unsigned char *q = (unsigned char*)VARDATA(query);

          res = true;
          for(i=0; res && i<SIGLEN(query); i++)
            if ( q[i] != 0xff )
              res = false;
        }
      break;
    case RDKitEquals:
      *recheck = true;

      if (!ISALLTRUE(key))
        {
          int i;
          unsigned char   *k = (unsigned char*)VARDATA(key),
            *q = (unsigned char*)VARDATA(query);

          if (SIGLEN(key) != SIGLEN(query))
            elog(ERROR, "All fingerprints should be the same length");

          for(i=0; res && i<SIGLEN(key); i++){
        	unsigned char temp = k[i] & q[i];
            if ( temp != q[i] || temp != k[i])
              res = false;
          }
        }
      break;
    default:
      elog(ERROR,"Unknown strategy: %d", strategy);
    }

  PG_RETURN_BOOL(res);
}
Esempio n. 15
0
Datum WTBtree_consistent(PG_FUNCTION_ARGS)
{	
	printf("------------------consistent\n");

	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	
	void	   *query = (void *) DatumGetTextP(PG_GETARG_DATUM(1));
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	bool		result;	
	/* Oid		subtype = PG_GETARG_OID(3); */
	
/*
GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R ok;

ok = gbt_var_key_readable(orge);

printf("ok.lower : %s\n", ok.lower);
printf("VARDATA(ok.lower) : %s\n", VARDATA(ok.lower));
printf("VARDATA(ok.upper) : %s\n", VARDATA(ok.upper));

printf("VARDATA_4B(ok.lower) : %s\n", VARDATA_4B(ok.lower));
printf("VARDATA_4B(ok.upper) : %s\n", VARDATA_4B(ok.upper));

*/
printf("strategy : %d\n", strategy);


char* temp;
temp = (char*) palloc(12);

memcpy(temp, "wx4fccknzng3", 12);

GeoCoord gCoord = geohash_decode(temp);

printf("gCoord.north : %lf\n", gCoord.north);
printf("gCoord.east : %lf\n", gCoord.east);
printf("gCoord.south : %lf\n", gCoord.south);
printf("gCoord.west : %lf\n", gCoord.west);

BOX2DF* tbox;
tbox = (BOX2DF*) palloc(sizeof(BOX2DF));

tbox->xmin = (float) gCoord.west;
tbox->ymin = (float) gCoord.south;
tbox->xmax = (float) gCoord.east;
tbox->ymax = (float) gCoord.north;


printf("temp : %s\n", temp);


BOX2DF query_gbox_index;
	gserialized_datum_get_box2df_p(query, &query_gbox_index);

	if (GIST_LEAF(entry))
	{
		result = gserialized_gist_consistent_leaf_2d(tbox,
		             &query_gbox_index, strategy);
	}
	else
	{
		result = gserialized_gist_consistent_internal_2d(tbox,
		             &query_gbox_index, strategy);
	}

/*
	BOX2DF query_gbox_index;
	gserialized_datum_get_box2df_p(query, &query_gbox_index);

	if (GIST_LEAF(entry))
	{
		result = gserialized_gist_consistent_leaf_2d(
		             (BOX2DF*)DatumGetPointer(entry->key),
		             &query_gbox_index, strategy);
	}
	else
	{
		result = gserialized_gist_consistent_internal_2d(
		             (BOX2DF*)DatumGetPointer(entry->key),
		             &query_gbox_index, strategy);
	}

*/

/*
	int size = 12;
	char *minPnt, *maxPnt, *cvtGeoHash;

	minPnt = (char*) palloc(size);
	maxPnt = (char*) palloc(size);
	cvtGeoHash = (char*) palloc(size);

	
	memcpy(minPnt, geohash_encode((double) query_gbox_index.ymin, (double) query_gbox_index.xmin, size), size);
	memcpy(maxPnt, geohash_encode((double) query_gbox_index.ymax, (double) query_gbox_index.xmax, size), size);

	cvtGeoHash = convert_GeoHash_from_box2d(minPnt, maxPnt, size);

	printf("-----------geohash_encode : %s\n", cvtGeoHash);	
*/
	/* PostgreSQL 8.4 and later require the RECHECK flag to be set here,
	   rather than being supplied as part of the operator class definition */

/*
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);

	LEAF_KEY key;

	memcpy(key, DatumGetPointer(entry->key), KEY_SIZE);

	INTERNAL_KEY *ikey = leafKey_to_internaKey(key);	


	*recheck = false;
*/	


	PG_RETURN_BOOL(result);
}
Esempio n. 16
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);
}