示例#1
0
 Datum spherecircle_cont_poly_com_neg (PG_FUNCTION_ARGS)
 {
   SPOLY   * poly = PG_GETARG_SPOLY( 0 ) ;
   SCIRCLE * circ = ( SCIRCLE  * ) PG_GETARG_POINTER ( 1 ) ;
   PG_RETURN_BOOL ( poly_circle_pos ( poly, circ ) != PGS_CIRCLE_CONT_POLY );
 }
示例#2
0
文件: isn.c 项目: adam8157/gpdb
Datum
weak_input_status(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(g_weak);
}
示例#3
0
/*
** 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 = PG_GETARG_ARRAYTYPE_P_COPY(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);
	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);
}
示例#4
0
Datum
ssl_is_used(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(MyProcPort->ssl != NULL);
}
示例#5
0
Datum
cdb_heap_test(PG_FUNCTION_ARGS)
{
	int		nSlots		= PG_GETARG_INT32(0);
	int		nToGenerate = PG_GETARG_INT32(1);
	int		seed		= PG_GETARG_INT32(2);
	bool	result = true;
	CdbHeap *cdbheap = NULL;
	int i;
	int *intvals;
	HeapValue* values;
	int *slotcounts;
	int *slotpositions;
	HeapValue *phv;

	Assert(nSlots >= 1 && nToGenerate >= 1 );

	cdbheap = CreateCdbHeap( nSlots, 
							cmpIntP,
							createIntP,
							copyIntP,
							switchIntP,
							NULL);
	/*
	 * Generate nToGenerate random integers
	 */
	intvals = (int *)palloc0( nToGenerate * sizeof(int) );
	srand( seed );

	for ( i=0; i<nToGenerate; i++ )
	{
		intvals[i] = rand();
	}

	// Now sort these
	qsort( intvals, nToGenerate, sizeof(int), cmpint );

	// Now allocate nSlots arrays for the sorted ints, and an array for the counts
	values = (HeapValue *)palloc0( nToGenerate * sizeof(HeapValue));
	slotcounts = (int *)palloc0( nSlots * sizeof(int) );
	slotpositions = (int *)palloc0( nSlots * sizeof(int) );

	// Now randomly assign the values to nSlots, preserving order
	for ( i=0; i<nToGenerate; i++ )
	{
		int slot = floor( ((double)rand() / ((double)RAND_MAX + 1 )) * nSlots);
		Assert( slot >= 0 && slot < nSlots);

		values[i].source = slot;
		values[i].value = intvals + i;
		slotcounts[slot]++;
	}

	elog( DEBUG4, "Slot counts follow" );
	int sum = 0;
	for ( i=0; i<nSlots; i++ )
	{
		if ( slotcounts[i] == 0 )
		{
			ereport(NOTICE,
					(errcode(ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH),
						errmsg("Function cdb_heap_test() cannot proceed, because not all slots got values."))
					);
			result = false;
			goto end;
		}

		sum += slotcounts[i];
		elog( DEBUG4, "slotcount[%d] = %d" , i, slotcounts[i]);
	}

	elog( DEBUG4, "slotcount total = %d" , sum);

	// Now add the first element from each slot to the heap.
	for ( i=0; i<nSlots; i++ )
	{
		int index = GetNextValueForSlot( values, i, slotpositions[i], nToGenerate );
		SetCdbHeapInitialValue( cdbheap, &values[index] );
		slotpositions[i] = index+1;
	}

	// Now grab lowest element from heap, and ask for the next element from the
	// same slot
	int lastval = INT_MIN;
	int lastslot;
	for ( i=0; i<nToGenerate; i++ )
	{
		HeapValue *phv = (HeapValue *)GetLowestValueFromCdbHeap( cdbheap );
		Assert( phv != NULL );
		if ( phv->value == NULL )
		{
			ereport(NOTICE,
					(errcode(ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH),
						errmsg("Function cdb_heap_test() failed. At index %d, value was NULL",
						i ))
					);
			result = false;
			goto end;
		}

		if ( lastval > *phv->value )
		{
			ereport(NOTICE,
					(errcode(ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH),
						errmsg("Function cdb_heap_test() failed. At index %d, value %d was smaller than previous value %d",
						i, *phv->value, lastval ))
					);
			result = false;
			goto end;
		}

		lastval = *phv->value;
		lastslot = phv->source;

		int index = GetNextValueForSlot( values, lastslot, slotpositions[lastslot], nToGenerate );

		if ( index == -1 )
			phv->value = NULL;
		else
		{
			phv = &values[index];
			slotpositions[lastslot] = index + 1;
		}

		MergeNewValueIntoCdbHeap( cdbheap, phv );
	}

	phv = GetLowestValueFromCdbHeap( cdbheap );
	Assert( phv != NULL && phv->value == NULL );

end:
	if ( cdbheap != NULL )
		DestroyCdbHeap( cdbheap );

	PG_RETURN_BOOL(result);
}
示例#6
0
Datum
plvdate_using_easter (PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(use_easter);
}
示例#7
0
Datum
spg_text_leaf_consistent(PG_FUNCTION_ARGS)
{
	spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0);
	spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1);
	int			level = in->level;
	text	   *leafValue,
			   *reconstrValue = NULL;
	char	   *fullValue;
	int			fullLen;
	bool		res;
	int			j;

	/* all tests are exact */
	out->recheck = false;

	leafValue = DatumGetTextPP(in->leafDatum);

	if (DatumGetPointer(in->reconstructedValue))
		reconstrValue = DatumGetTextP(in->reconstructedValue);

	Assert(level == 0 ? reconstrValue == NULL :
		   VARSIZE_ANY_EXHDR(reconstrValue) == level);

	/* Reconstruct the full string represented by this leaf tuple */
	fullLen = level + VARSIZE_ANY_EXHDR(leafValue);
	if (VARSIZE_ANY_EXHDR(leafValue) == 0 && level > 0)
	{
		fullValue = VARDATA(reconstrValue);
		out->leafValue = PointerGetDatum(reconstrValue);
	}
	else
	{
		text	   *fullText = palloc(VARHDRSZ + fullLen);

		SET_VARSIZE(fullText, VARHDRSZ + fullLen);
		fullValue = VARDATA(fullText);
		if (level)
			memcpy(fullValue, VARDATA(reconstrValue), level);
		if (VARSIZE_ANY_EXHDR(leafValue) > 0)
			memcpy(fullValue + level, VARDATA_ANY(leafValue),
				   VARSIZE_ANY_EXHDR(leafValue));
		out->leafValue = PointerGetDatum(fullText);
	}

	/* Perform the required comparison(s) */
	res = true;
	for (j = 0; j < in->nkeys; j++)
	{
		StrategyNumber strategy = in->scankeys[j].sk_strategy;
		text	   *query = DatumGetTextPP(in->scankeys[j].sk_argument);
		int			queryLen = VARSIZE_ANY_EXHDR(query);
		int			r;

		if (strategy > 10)
		{
			/* Collation-aware comparison */
			strategy -= 10;

			/* If asserts enabled, verify encoding of reconstructed string */
			Assert(pg_verifymbstr(fullValue, fullLen, false));

			r = varstr_cmp(fullValue, Min(queryLen, fullLen),
						   VARDATA_ANY(query), Min(queryLen, fullLen),
						   PG_GET_COLLATION());
		}
		else
		{
			/* Non-collation-aware comparison */
			r = memcmp(fullValue, VARDATA_ANY(query), Min(queryLen, fullLen));
		}

		if (r == 0)
		{
			if (queryLen > fullLen)
				r = -1;
			else if (queryLen < fullLen)
				r = 1;
		}

		switch (strategy)
		{
			case BTLessStrategyNumber:
				res = (r < 0);
				break;
			case BTLessEqualStrategyNumber:
				res = (r <= 0);
				break;
			case BTEqualStrategyNumber:
				res = (r == 0);
				break;
			case BTGreaterEqualStrategyNumber:
				res = (r >= 0);
				break;
			case BTGreaterStrategyNumber:
				res = (r > 0);
				break;
			default:
				elog(ERROR, "unrecognized strategy number: %d",
					 in->scankeys[j].sk_strategy);
				res = false;
				break;
		}

		if (!res)
			break;				/* no need to consider remaining conditions */
	}

	PG_RETURN_BOOL(res);
}
示例#8
0
 Datum spherepoly_cont_ellipse_com (PG_FUNCTION_ARGS)
 {
   SELLIPSE * ell  = ( SELLIPSE * ) PG_GETARG_POINTER ( 0 ) ;
   SPOLY    * poly = PG_GETARG_SPOLY( 1 ) ;
   PG_RETURN_BOOL ( poly_ellipse_pos ( poly, ell ) == PGS_POLY_CONT_ELLIPSE );
 }
示例#9
0
/*
 * Returns bool with current on-line backup mode, a global state.
 */
Datum
pg_is_in_backup(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(BackupInProgress());
}
示例#10
0
 Datum spherepoly_cont_poly_com_neg (PG_FUNCTION_ARGS)
 {
   SPOLY   * poly1 = PG_GETARG_SPOLY( 1 ) ;
   SPOLY   * poly2 = PG_GETARG_SPOLY( 0 ) ;
   PG_RETURN_BOOL ( poly_poly_pos ( poly1, poly2, FALSE ) !=  PGS_POLY_CONT );
 }
示例#11
0
 Datum spherepoly_overlap_poly_neg (PG_FUNCTION_ARGS)
 {
   SPOLY   * poly1 = PG_GETARG_SPOLY( 0 ) ;
   SPOLY   * poly2 = PG_GETARG_SPOLY( 1 ) ;
   PG_RETURN_BOOL ( poly_poly_pos ( poly1, poly2, FALSE ) == PGS_POLY_AVOID );
 }
示例#12
0
 Datum spherepoly_overlap_line_com_neg (PG_FUNCTION_ARGS)
 {
   SPOLY   * poly = PG_GETARG_SPOLY( 1 ) ;
   SLine   * line = ( SLine * ) PG_GETARG_POINTER ( 0 ) ;
   PG_RETURN_BOOL ( poly_line_pos ( poly, line ) == PGS_LINE_POLY_AVOID );
 }
示例#13
0
 Datum spherepoly_cont_line_com_neg (PG_FUNCTION_ARGS)
 {
   SPOLY   * poly = PG_GETARG_SPOLY( 1 ) ;
   SLine   * line = ( SLine  * ) PG_GETARG_POINTER ( 0 ) ;
   PG_RETURN_BOOL ( poly_line_pos ( poly, line ) != PGS_POLY_CONT_LINE );
 }
示例#14
0
 Datum spherepoly_overlap_circle_com_neg (PG_FUNCTION_ARGS)
 {
   SPOLY   * poly = PG_GETARG_SPOLY( 1 ) ;
   SCIRCLE * circ = ( SCIRCLE  * ) PG_GETARG_POINTER ( 0 ) ;
   PG_RETURN_BOOL ( poly_circle_pos ( poly, circ ) == PGS_CIRCLE_POLY_AVOID );
 }
示例#15
0
Datum
gp_add_persistent_database_node_entry(PG_FUNCTION_ARGS)
{
	NYI;
	PG_RETURN_BOOL(true);
}
示例#16
0
文件: mol_op.c 项目: Acpharis/rdkit
Datum
is_valid_smarts(PG_FUNCTION_ARGS) {
  char  *data = PG_GETARG_CSTRING(0);
  PG_RETURN_BOOL(isValidSmarts(data));
}
示例#17
0
Datum
gp_add_persistent_relation_node_entry(PG_FUNCTION_ARGS)
{
	Datum				values[Natts_gp_persistent_relation_node];
	ItemPointerData		persistentTid;
	int64				persistentSerialNum;
	int					i;
	
	/* Must be super user */
	if (!superuser())
		elog(ERROR, "permission denied");

	/* Check input arguments */

	/*
	 * First parameter is the tid, remaining parameters should match the column
	 * types in gp_persistent_relation_node.
	 */
	if (PG_NARGS() != Natts_gp_persistent_relation_node + 1)
	{
		Oid		 procOid  = fcinfo->flinfo->fn_oid;
		char	*procName = format_procedure(procOid);

		elog(ERROR, "function '%s' received unexpected number of arguments",
			 procName);
	}

	/* 
	 * For the moment we don't support inserting at particular tids, 
	 * initial argument MUST be null.
	 */
	if (!PG_ARGISNULL(0))
		elog(ERROR, "direct tid assignment to %s is not yet supported",
			 "gp_persistent_relation_node");
	
	/* 
	 * validate that datatypes match expected, e.g. no one went and changed
	 * the catalog without updating this function.
	 */

	/* Build up the tuple we want to add */
	memset(&persistentTid, 0, sizeof(persistentTid));
	for (i = 0; i < Natts_gp_persistent_relation_node; i++)
	{
		if (PG_ARGISNULL(i+1))
			elog(ERROR, "null arguments not supported");
		values[i] = PG_GETARG_DATUM(i+1);
	}
	
	/*
	 * TODO: Validate the tuple
	 *   - Specified database exists
	 *   - Specified tablespace exists
	 *   - Specified relfile is in the filesystem
	 *   - etc.
	 */

	/* Add it to the table */
	PersistentFileSysObj_AddTuple(PersistentFsObjType_RelationFile,
								  values,
								  true, /* flushToXlog */
								  &persistentTid,
								  &persistentSerialNum);

	/* explain how we re-wrote that tuple */
	elog(NOTICE,
		 "inserted 1 row (TID %s, persistent_serial_num " INT64_FORMAT ")",
		 ItemPointerToString(&persistentTid),
		 persistentSerialNum);

	PG_RETURN_BOOL(true);
}
示例#18
0
文件: mol_op.c 项目: Acpharis/rdkit
Datum
is_valid_ctab(PG_FUNCTION_ARGS) {
  char  *data = PG_GETARG_CSTRING(0);
  PG_RETURN_BOOL(isValidCTAB(data));
}
示例#19
0
Datum
plvdate_including_start (PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(include_start);
}
示例#20
0
Datum
gp_update_persistent_tablespace_node_entry(PG_FUNCTION_ARGS)
{
	NYI;
	PG_RETURN_BOOL(true);
}
示例#21
0
Datum
gin_trgm_consistent(PG_FUNCTION_ARGS)
{
	bool	   *check = (bool *) PG_GETARG_POINTER(0);
	StrategyNumber strategy = PG_GETARG_UINT16(1);

	/* text    *query = PG_GETARG_TEXT_P(2); */
	int32		nkeys = PG_GETARG_INT32(3);
	Pointer    *extra_data = (Pointer *) PG_GETARG_POINTER(4);
	bool	   *recheck = (bool *) PG_GETARG_POINTER(5);
	bool		res;
	int32		i,
				ntrue;

	/* All cases served by this function are inexact */
	*recheck = true;

	switch (strategy)
	{
		case SimilarityStrategyNumber:
			/* Count the matches */
			ntrue = 0;
			for (i = 0; i < nkeys; i++)
			{
				if (check[i])
					ntrue++;
			}

			/*--------------------
			 * If DIVUNION is defined then similarity formula is:
			 * c / (len1 + len2 - c)
			 * where c is number of common trigrams and it stands as ntrue in
			 * this code.  Here we don't know value of len2 but we can assume
			 * that c (ntrue) is a lower bound of len2, so upper bound of
			 * similarity is:
			 * c / (len1 + c - c)  => c / len1
			 * If DIVUNION is not defined then similarity formula is:
			 * c / max(len1, len2)
			 * And again, c (ntrue) is a lower bound of len2, but c <= len1
			 * just by definition and, consequently, upper bound of
			 * similarity is just c / len1.
			 * So, independly on DIVUNION the upper bound formula is the same.
			 */
			res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
			break;
		case ILikeStrategyNumber:
#ifndef IGNORECASE
			elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
#endif
			/* FALL THRU */
		case LikeStrategyNumber:
			/* Check if all extracted trigrams are presented. */
			res = true;
			for (i = 0; i < nkeys; i++)
			{
				if (!check[i])
				{
					res = false;
					break;
				}
			}
			break;
		case RegExpICaseStrategyNumber:
#ifndef IGNORECASE
			elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
#endif
			/* FALL THRU */
		case RegExpStrategyNumber:
			if (nkeys < 1)
			{
				/* Regex processing gave no result: do full index scan */
				res = true;
			}
			else
				res = trigramsMatchGraph((TrgmPackedGraph *) extra_data[0],
										 check);
			break;
		default:
			elog(ERROR, "unrecognized strategy number: %d", strategy);
			res = false;		/* keep compiler quiet */
			break;
	}

	PG_RETURN_BOOL(res);
}
示例#22
0
Datum
gp_update_persistent_relation_node_entry(PG_FUNCTION_ARGS)
{
	NYI;
	PG_RETURN_BOOL(true);
}
示例#23
0
Datum
ssl_client_cert_present(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(MyProcPort->peer != NULL);
}
示例#24
0
Datum
gp_delete_global_sequence_entry(PG_FUNCTION_ARGS)
{
	NYI;
	PG_RETURN_BOOL(true);
}
示例#25
0
文件: hash.c 项目: GisKook/Gis
/*
 *	hashgettuple() -- Get the next tuple in the scan.
 */
Datum
hashgettuple(PG_FUNCTION_ARGS)
{
	IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
	ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
	HashScanOpaque so = (HashScanOpaque) scan->opaque;
	Relation	rel = scan->indexRelation;
	Buffer		buf;
	Page		page;
	OffsetNumber offnum;
	ItemPointer current;
	bool		res;

	/* Hash indexes are always lossy since we store only the hash code */
	scan->xs_recheck = true;

	/*
	 * We hold pin but not lock on current buffer while outside the hash AM.
	 * Reacquire the read lock here.
	 */
	if (BufferIsValid(so->hashso_curbuf))
		_hash_chgbufaccess(rel, so->hashso_curbuf, HASH_NOLOCK, HASH_READ);

	/*
	 * If we've already initialized this scan, we can just advance it in the
	 * appropriate direction.  If we haven't done so yet, we call a routine to
	 * get the first item in the scan.
	 */
	current = &(so->hashso_curpos);
	if (ItemPointerIsValid(current))
	{
		/*
		 * An insertion into the current index page could have happened while
		 * we didn't have read lock on it.  Re-find our position by looking
		 * for the TID we previously returned.	(Because we hold share lock on
		 * the bucket, no deletions or splits could have occurred; therefore
		 * we can expect that the TID still exists in the current index page,
		 * at an offset >= where we were.)
		 */
		OffsetNumber maxoffnum;

		buf = so->hashso_curbuf;
		Assert(BufferIsValid(buf));
		page = BufferGetPage(buf);
		maxoffnum = PageGetMaxOffsetNumber(page);
		for (offnum = ItemPointerGetOffsetNumber(current);
			 offnum <= maxoffnum;
			 offnum = OffsetNumberNext(offnum))
		{
			IndexTuple	itup;

			itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
			if (ItemPointerEquals(&(so->hashso_heappos), &(itup->t_tid)))
				break;
		}
		if (offnum > maxoffnum)
			elog(ERROR, "failed to re-find scan position within index \"%s\"",
				 RelationGetRelationName(rel));
		ItemPointerSetOffsetNumber(current, offnum);

		/*
		 * Check to see if we should kill the previously-fetched tuple.
		 */
		if (scan->kill_prior_tuple)
		{
			/*
			 * Yes, so mark it by setting the LP_DEAD state in the item flags.
			 */
			ItemIdMarkDead(PageGetItemId(page, offnum));

			/*
			 * Since this can be redone later if needed, it's treated the same
			 * as a commit-hint-bit status update for heap tuples: we mark the
			 * buffer dirty but don't make a WAL log entry.
			 */
			SetBufferCommitInfoNeedsSave(buf);
		}

		/*
		 * Now continue the scan.
		 */
		res = _hash_next(scan, dir);
	}
	else
		res = _hash_first(scan, dir);

	/*
	 * Skip killed tuples if asked to.
	 */
	if (scan->ignore_killed_tuples)
	{
		while (res)
		{
			offnum = ItemPointerGetOffsetNumber(current);
			page = BufferGetPage(so->hashso_curbuf);
			if (!ItemIdIsDead(PageGetItemId(page, offnum)))
				break;
			res = _hash_next(scan, dir);
		}
	}

	/* Release read lock on current buffer, but keep it pinned */
	if (BufferIsValid(so->hashso_curbuf))
		_hash_chgbufaccess(rel, so->hashso_curbuf, HASH_READ, HASH_NOLOCK);

	/* Return current heap TID on success */
	scan->xs_ctup.t_self = so->hashso_heappos;

	PG_RETURN_BOOL(res);
}
示例#26
0
Datum
gp_delete_relation_node_entry(PG_FUNCTION_ARGS)
{
	NYI;
	PG_RETURN_BOOL(true);
}
示例#27
0
Datum
ltree_ne(PG_FUNCTION_ARGS)
{
	RUNCMP
		PG_RETURN_BOOL((res != 0) ? true : false);
}
示例#28
0
Datum
gp_add_persistent_filespace_node_entry(PG_FUNCTION_ARGS)
{
	NYI;
	PG_RETURN_BOOL(true);
}
示例#29
0
/*
 * Returns bool with current recovery mode, a global state.
 */
Datum
pg_is_in_recovery(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(RecoveryInProgress());
}
示例#30
0
 Datum spherepoly_cont_circle_com (PG_FUNCTION_ARGS)
 {
   SCIRCLE * circ = ( SCIRCLE  * ) PG_GETARG_POINTER ( 0 ) ;
   SPOLY   * poly = PG_GETARG_SPOLY( 1 ) ;
   PG_RETURN_BOOL ( poly_circle_pos ( poly, circ ) == PGS_POLY_CONT_CIRCLE );
 }