Exemple #1
0
static bool
gbt_dategt(const void *a, const void *b)
{
	return DatumGetBool(
						DirectFunctionCall2(date_gt, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b)))
		);
}
Exemple #2
0
bool type_is_domain(char *type_name, Oid *base_type) {
    bool       rc;
    StringInfo query;

    SPI_connect();
    query = makeStringInfo();
    appendStringInfo(query, "SELECT typtype = 'd', typbasetype FROM pg_type WHERE typname = %s", TextDatumGetCString(DirectFunctionCall1(quote_literal, CStringGetTextDatum(type_name))));

    if (SPI_execute(query->data, true, 1) != SPI_OK_SELECT)
        elog(ERROR, "Problem determing if %s is a domain with query: %s", type_name, query->data);

    if (SPI_processed == 0) {
        rc = false;
    } else {
        bool  isnull;
        Datum d;

        d  = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
        rc = isnull || DatumGetBool(d);

        d = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull);
        *base_type = isnull ? InvalidOid : DatumGetObjectId(d);
    }

    SPI_finish();

    return rc;
}
Exemple #3
0
static bool
array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
{
	int			num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
	ltree	   *item = (ltree *) ARR_DATA_PTR(la);

	if (ARR_NDIM(la) > 1)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("array must be one-dimensional")));
	if (array_contains_nulls(la))
		ereport(ERROR,
				(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
				 errmsg("array must not contain nulls")));

	if (found)
		*found = NULL;
	while (num > 0)
	{
		if (DatumGetBool(DirectFunctionCall2(callback,
							 PointerGetDatum(item), PointerGetDatum(param))))
		{

			if (found)
				*found = item;
			return true;
		}
		num--;
		item = NEXTVAL(item);
	}

	return false;
}
Exemple #4
0
static bool
gbt_bitlt(const void *a, const void *b, Oid collation)
{
	return DatumGetBool(DirectFunctionCall2(bitlt,
											PointerGetDatum(a),
											PointerGetDatum(b)));
}
/*
 * execTuplesMatch
 *		Return true if two tuples match in all the indicated fields.
 *
 * This actually implements SQL's notion of "not distinct".  Two nulls
 * match, a null and a not-null don't match.
 *
 * slot1, slot2: the tuples to compare (must have same columns!)
 * numCols: the number of attributes to be examined
 * matchColIdx: array of attribute column numbers
 * eqFunctions: array of fmgr lookup info for the equality functions to use
 * evalContext: short-term memory context for executing the functions
 *
 * NB: evalContext is reset each time!
 */
bool
execTuplesMatch(TupleTableSlot *slot1,
				TupleTableSlot *slot2,
				int numCols,
				AttrNumber *matchColIdx,
				FmgrInfo *eqfunctions,
				MemoryContext evalContext)
{
	MemoryContext oldContext;
	bool		result;
	int			i;

	/* Reset and switch into the temp context. */
	MemoryContextReset(evalContext);
	oldContext = MemoryContextSwitchTo(evalContext);

	/*
	 * We cannot report a match without checking all the fields, but we can
	 * report a non-match as soon as we find unequal fields.  So, start
	 * comparing at the last field (least significant sort key). That's the
	 * most likely to be different if we are dealing with sorted input.
	 */
	result = true;

	for (i = numCols; --i >= 0;)
	{
		AttrNumber	att = matchColIdx[i];
		Datum		attr1,
					attr2;
		bool		isNull1,
					isNull2;

		attr1 = slot_getattr(slot1, att, &isNull1);

		attr2 = slot_getattr(slot2, att, &isNull2);

		if (isNull1 != isNull2)
		{
			result = false;		/* one null and one not; they aren't equal */
			break;
		}

		if (isNull1)
			continue;			/* both are null, treat as equal */

		/* Apply the type-specific equality function */

		if (!DatumGetBool(FunctionCall2(&eqfunctions[i],
										attr1, attr2)))
		{
			result = false;		/* they aren't equal */
			break;
		}
	}

	MemoryContextSwitchTo(oldContext);

	return result;
}
Exemple #6
0
/*
 *		tintervalov		- returns true iff tinterval i1 (partially) overlaps i2
 */
Datum
tintervalov(PG_FUNCTION_ARGS)
{
	TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
	TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);

	if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
		PG_RETURN_BOOL(false);
	if (DatumGetBool(DirectFunctionCall2(abstimelt,
										 AbsoluteTimeGetDatum(i1->data[1]),
									   AbsoluteTimeGetDatum(i2->data[0]))) ||
		DatumGetBool(DirectFunctionCall2(abstimegt,
										 AbsoluteTimeGetDatum(i1->data[0]),
										 AbsoluteTimeGetDatum(i2->data[1]))))
		PG_RETURN_BOOL(false);
	PG_RETURN_BOOL(true);
}
Exemple #7
0
static bool
gbt_textlt(const void *a, const void *b)
{
	return DatumGetBool(DirectFunctionCall2Coll(text_lt,
												DEFAULT_COLLATION_OID,
												PointerGetDatum(a),
												PointerGetDatum(b)));
}
Exemple #8
0
static bool
gbt_textle(const void *a, const void *b, Oid collation)
{
	return DatumGetBool(DirectFunctionCall2Coll(text_le,
												collation,
												PointerGetDatum(a),
												PointerGetDatum(b)));
}
Exemple #9
0
void GpPersistentRelationNode_GetValues(
	Datum									*values,

	Oid 									*tablespaceOid,
	Oid 									*databaseOid,
	Oid 									*relfilenodeOid,
	int32									*segmentFileNum,
	PersistentFileSysRelStorageMgr			*relationStorageManager,
	PersistentFileSysState					*persistentState,
	int64									*createMirrorDataLossTrackingSessionNum,
	MirroredObjectExistenceState			*mirrorExistenceState,
	MirroredRelDataSynchronizationState 	*mirrorDataSynchronizationState,
	bool									*mirrorBufpoolMarkedForScanIncrementalResync,
	int64									*mirrorBufpoolResyncChangedPageCount,
	XLogRecPtr								*mirrorBufpoolResyncCkptLoc,
	BlockNumber								*mirrorBufpoolResyncCkptBlockNum,
	int64									*mirrorAppendOnlyLossEof,
	int64									*mirrorAppendOnlyNewEof,
	PersistentFileSysRelBufpoolKind 		*relBufpoolKind,
	TransactionId							*parentXid,
	int64									*persistentSerialNum)
{
	*tablespaceOid = DatumGetObjectId(values[Anum_gp_persistent_relation_node_tablespace_oid - 1]);

	*databaseOid = DatumGetObjectId(values[Anum_gp_persistent_relation_node_database_oid - 1]);

	*relfilenodeOid = DatumGetObjectId(values[Anum_gp_persistent_relation_node_relfilenode_oid - 1]);

	*segmentFileNum = DatumGetInt32(values[Anum_gp_persistent_relation_node_segment_file_num - 1]);

	*relationStorageManager = (PersistentFileSysRelStorageMgr)DatumGetInt16(values[Anum_gp_persistent_relation_node_relation_storage_manager - 1]);

	*persistentState = (PersistentFileSysState)DatumGetInt16(values[Anum_gp_persistent_relation_node_persistent_state - 1]);

	*createMirrorDataLossTrackingSessionNum = DatumGetInt64(values[Anum_gp_persistent_relation_node_create_mirror_data_loss_tracking_session_num - 1]);

	*mirrorExistenceState = (MirroredObjectExistenceState)DatumGetInt16(values[Anum_gp_persistent_relation_node_mirror_existence_state - 1]);

	*mirrorDataSynchronizationState = (MirroredRelDataSynchronizationState)DatumGetInt16(values[Anum_gp_persistent_relation_node_mirror_data_synchronization_state - 1]);

	*mirrorBufpoolMarkedForScanIncrementalResync = DatumGetBool(values[Anum_gp_persistent_relation_node_mirror_bufpool_marked_for_scan_incremental_resync - 1]);

	*mirrorBufpoolResyncChangedPageCount = DatumGetInt64(values[Anum_gp_persistent_relation_node_mirror_bufpool_resync_changed_page_count - 1]);

	*mirrorBufpoolResyncCkptLoc = *((XLogRecPtr*) DatumGetPointer(values[Anum_gp_persistent_relation_node_mirror_bufpool_resync_ckpt_loc - 1]));

	*mirrorBufpoolResyncCkptBlockNum = (BlockNumber)DatumGetInt32(values[Anum_gp_persistent_relation_node_mirror_bufpool_resync_ckpt_block_num - 1]);

	*mirrorAppendOnlyLossEof = DatumGetInt64(values[Anum_gp_persistent_relation_node_mirror_append_only_loss_eof - 1]);

	*mirrorAppendOnlyNewEof = DatumGetInt64(values[Anum_gp_persistent_relation_node_mirror_append_only_new_eof - 1]);

	*relBufpoolKind = (PersistentFileSysRelBufpoolKind)DatumGetInt32(values[Anum_gp_persistent_relation_node_relation_bufpool_kind - 1]);

	*parentXid = (TransactionId)DatumGetInt32(values[Anum_gp_persistent_relation_node_parent_xid - 1]);

	*persistentSerialNum = DatumGetInt64(values[Anum_gp_persistent_relation_node_persistent_serial_num - 1]);
}
Exemple #10
0
/*
 *		intinterval		- returns true iff absolute date is in the tinterval
 */
Datum
intinterval(PG_FUNCTION_ARGS)
{
	AbsoluteTime t = PG_GETARG_ABSOLUTETIME(0);
	TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(1);

	if (tinterval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)
	{
		if (DatumGetBool(DirectFunctionCall2(abstimege,
											 AbsoluteTimeGetDatum(t),
								AbsoluteTimeGetDatum(tinterval->data[0]))) &&
			DatumGetBool(DirectFunctionCall2(abstimele,
											 AbsoluteTimeGetDatum(t),
								  AbsoluteTimeGetDatum(tinterval->data[1]))))
			PG_RETURN_BOOL(true);
	}
	PG_RETURN_BOOL(false);
}
/**
 * Convert postgres Datum into a ConcreteValue object.
 */
AbstractValueSPtr AbstractPGValue::DatumToValue(bool inMemoryIsWritable,
    Oid inTypeID, Datum inDatum) const {
        
    // First check if datum is rowtype
    if (type_is_rowtype(inTypeID)) {
        HeapTupleHeader pgTuple = DatumGetHeapTupleHeader(inDatum);
        return AbstractValueSPtr(new PGValue<HeapTupleHeader>(pgTuple));
    } else if (type_is_array(inTypeID)) {
        ArrayType *pgArray = DatumGetArrayTypeP(inDatum);
        
        if (ARR_NDIM(pgArray) != 1)
            throw std::invalid_argument("Multidimensional arrays not yet supported");
        
        if (ARR_HASNULL(pgArray))
            throw std::invalid_argument("Arrays with NULLs not yet supported");
        
        switch (ARR_ELEMTYPE(pgArray)) {
            case FLOAT8OID: {
                MemHandleSPtr memoryHandle(new PGArrayHandle(pgArray));
                
                if (inMemoryIsWritable) {
                    return AbstractValueSPtr(
                        new ConcreteValue<Array<double> >(
                            Array<double>(memoryHandle,
                                boost::extents[ ARR_DIMS(pgArray)[0] ])
                            )
                        );
                } else {
                    return AbstractValueSPtr(
                        new ConcreteValue<Array_const<double> >(
                            Array_const<double>(memoryHandle,
                                boost::extents[ ARR_DIMS(pgArray)[0] ])
                            )
                        );
                }
            }
        }
    }

    switch (inTypeID) {
        case BOOLOID: return AbstractValueSPtr(
            new ConcreteValue<bool>( DatumGetBool(inDatum) ));
        case INT2OID: return AbstractValueSPtr(
            new ConcreteValue<int16_t>( DatumGetInt16(inDatum) ));
        case INT4OID: return AbstractValueSPtr(
            new ConcreteValue<int32_t>( DatumGetInt32(inDatum) ));
        case INT8OID: return AbstractValueSPtr(
            new ConcreteValue<int64_t>( DatumGetInt64(inDatum) ));
        case FLOAT4OID: return AbstractValueSPtr(
            new ConcreteValue<float>( DatumGetFloat4(inDatum) ));
        case FLOAT8OID: return AbstractValueSPtr(
            new ConcreteValue<double>( DatumGetFloat8(inDatum) ));
    }
    
    return AbstractValueSPtr();
}
Exemple #12
0
static bool
gbt_tsle(const void *a, const void *b, FmgrInfo *flinfo)
{
	const Timestamp *aa = (const Timestamp *) a;
	const Timestamp *bb = (const Timestamp *) b;

	return DatumGetBool(DirectFunctionCall2(timestamp_le,
											TimestampGetDatumFast(*aa),
											TimestampGetDatumFast(*bb)));
}
Exemple #13
0
static bool
gbt_timelt(const void *a, const void *b)
{
	const TimeADT *aa = (const TimeADT *) a;
	const TimeADT *bb = (const TimeADT *) b;

	return DatumGetBool(DirectFunctionCall2(time_lt,
											TimeADTGetDatumFast(*aa),
											TimeADTGetDatumFast(*bb)));
}
Exemple #14
0
static bool
gbt_tslt(const void *a, const void *b)
{
	const Timestamp *aa = (const Timestamp *) a;
	const Timestamp *bb = (const Timestamp *) b;

	return DatumGetBool(DirectFunctionCall2(timestamp_lt,
											TimestampGetDatumFast(*aa),
											TimestampGetDatumFast(*bb)));
}
Exemple #15
0
static inline
bool
ipaddr_comparison_bool(Datum d1, Datum d2,
					   bool mismatch_af1, bool mismatch_af2,
					   PGFunction ip4func, PGFunction ip6func)
{
    IP_P ipp1 = DatumGetIP_P(d1);
    IP_P ipp2 = DatumGetIP_P(d2);
	IP ip1;
	IP ip2;
	int af1 = ip_unpack(ipp1, &ip1);
	int af2 = ip_unpack(ipp2, &ip2);
	bool retval;

	if (af1 != af2)
	{
		retval = (af1 > af2) ? mismatch_af1 : mismatch_af2;
	}
	else
	{
		switch (af1)
		{
			case PGSQL_AF_INET:
				retval = DatumGetBool(DirectFunctionCall2(ip4func, IP4GetDatum(ip1.ip4), IP4GetDatum(ip2.ip4)));
				break;

			case PGSQL_AF_INET6:
				retval = DatumGetBool(DirectFunctionCall2(ip6func, IP6PGetDatum(&ip1.ip6), IP6PGetDatum(&ip2.ip6)));
				break;

			default:
				ipaddr_internal_error();
		}
	}

	if ((Pointer)ipp1 != DatumGetPointer(d1))
		pfree(ipp1);
	if ((Pointer)ipp2 != DatumGetPointer(d2))
		pfree(ipp2);

    return retval;
}
Exemple #16
0
Datum
_int_different(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(!DatumGetBool(
								 DirectFunctionCall2(
													 _int_same,
									   PointerGetDatum(PG_GETARG_POINTER(0)),
										PointerGetDatum(PG_GETARG_POINTER(1))
													 )
								 ));
}
Exemple #17
0
/*
 * Turn a scalar Datum into JSON, appending the string to "result".
 *
 * Hand off a non-scalar datum to composite_to_json or array_to_json_internal
 * as appropriate.
 */
static void
datum_to_json(Datum val, bool is_null, StringInfo result,
			  TYPCATEGORY tcategory, Oid typoutputfunc)
{
	char	   *outputstr;

	if (is_null)
	{
		appendStringInfoString(result, "null");
		return;
	}

	switch (tcategory)
	{
		case TYPCATEGORY_ARRAY:
			array_to_json_internal(val, result, false);
			break;
		case TYPCATEGORY_COMPOSITE:
			composite_to_json(val, result, false);
			break;
		case TYPCATEGORY_BOOLEAN:
			if (DatumGetBool(val))
				appendStringInfoString(result, "true");
			else
				appendStringInfoString(result, "false");
			break;
		case TYPCATEGORY_NUMERIC:
			outputstr = OidOutputFunctionCall(typoutputfunc, val);

			/*
			 * Don't call escape_json here if it's a valid JSON number.
			 * Numeric output should usually be a valid JSON number and JSON
			 * numbers shouldn't be quoted. Quote cases like "Nan" and
			 * "Infinity", however.
			 */
			if (strpbrk(outputstr, NON_NUMERIC_LETTER) == NULL)
				appendStringInfoString(result, outputstr);
			else
				escape_json(result, outputstr);
			pfree(outputstr);
			break;
		case TYPCATEGORY_JSON:
			/* JSON will already be escaped */
			outputstr = OidOutputFunctionCall(typoutputfunc, val);
			appendStringInfoString(result, outputstr);
			pfree(outputstr);
			break;
		default:
			outputstr = OidOutputFunctionCall(typoutputfunc, val);
			escape_json(result, outputstr);
			pfree(outputstr);
			break;
	}
}
Exemple #18
0
Datum
_int_contained(PG_FUNCTION_ARGS)
{
	PG_RETURN_BOOL(DatumGetBool(
								DirectFunctionCall2(
													_int_contains,
									   PointerGetDatum(PG_GETARG_POINTER(1)),
										PointerGetDatum(PG_GETARG_POINTER(0))
													)
								));
}
Exemple #19
0
static void
execute_pg_settings_logger(config_log_objects *objects) {

	int		ret;
	bool	isnull;
	StringInfoData	buf;


	SetCurrentStatementStartTimestamp();
	StartTransactionCommand();
	SPI_connect();
	PushActiveSnapshot(GetTransactionSnapshot());
	pgstat_report_activity(STATE_RUNNING, "executing configuration logger function");

	initStringInfo(&buf);

	appendStringInfo(
		&buf,
		"SELECT %s.%s()",
		config_log_schema,
		objects->function_name
		);

	ret = SPI_execute(buf.data, false, 0);
	if (ret != SPI_OK_SELECT)
	{
		elog(FATAL, "SPI_execute failed: error code %d", ret);
	}

	if (SPI_processed != 1)
	{
		elog(FATAL, "not a singleton result");
	}

	log_info("pg_settings_logger() executed");

	if(DatumGetBool(SPI_getbinval(SPI_tuptable->vals[0],
				  SPI_tuptable->tupdesc,
				  1, &isnull)))
	{
		log_info("Configuration changes recorded");
	}
	else
	{
		log_info("No configuration changes detected");
	}

   	SPI_finish();
	PopActiveSnapshot();
	CommitTransactionCommand();
	pgstat_report_activity(STATE_IDLE, NULL);
}
Exemple #20
0
Interval *
abs_interval(Interval *a)
{
	static Interval zero = {0, 0, 0};

	if (DatumGetBool(DirectFunctionCall2(interval_lt,
										 IntervalPGetDatum(a),
										 IntervalPGetDatum(&zero))))
		a = DatumGetIntervalP(DirectFunctionCall1(interval_um,
												  IntervalPGetDatum(a)));

	return a;
}
Exemple #21
0
static PyObject *
PLyBool_FromBool(PLyDatumToOb *arg, Datum d)
{
	/*
	 * We would like to use Py_RETURN_TRUE and Py_RETURN_FALSE here for
	 * generating SQL from trigger functions, but those are only supported in
	 * Python >= 2.3, and we support older versions.
	 * http://docs.python.org/api/boolObjects.html
	 */
	if (DatumGetBool(d))
		return PyBool_FromLong(1);
	return PyBool_FromLong(0);
}
Exemple #22
0
/*
** Equality method
*/
Datum
gbox_same(PG_FUNCTION_ARGS)
{
	BOX		   *b1 = (BOX *) PG_GETARG_POINTER(0);
	BOX		   *b2 = (BOX *) PG_GETARG_POINTER(1);
	bool	   *result = (bool *) PG_GETARG_POINTER(2);

	if (b1 && b2)
		*result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), PointerGetDatum(b2)));
	else
		*result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE;
	PG_RETURN_POINTER(result);
}
Exemple #23
0
/*
 * Test whether key1 matches key2. Since the equality functions may leak,
 * reset the temporary context at each call and do all equality calculation
 * in that context.
 */
static int
build_match_key(const void *key1, const void *key2, Size keysize __attribute__((unused)))
{
    Assert(key1);
    Assert(key2);

    BMBuildHashKey *keyData1 = (BMBuildHashKey*)key1;
	Datum *k1 = keyData1->attributeValueArr;
	bool *isNull1 = keyData1->isNullArr;
	
	BMBuildHashKey *keyData2 = (BMBuildHashKey*)key2;
	Datum *k2 = keyData2->attributeValueArr;
	bool *isNull2 = keyData2->isNullArr;
	
    int numKeys = cur_bmbuild->natts;

	int i;
	MemoryContext old;
	int result = 0;

	MemoryContextReset(cur_bmbuild->tmpcxt);
	old = MemoryContextSwitchTo(cur_bmbuild->tmpcxt);

	for(i = 0; i < numKeys; i++)
	{
	    if (isNull1[i] && isNull2[i])
        {
            /* both nulls -- treat as equal so we group them together */
        }
        else if ( isNull1[i] || isNull2[i])
        {
            /* one is null and one non-null -- this is inequal */
            result = 1;
            break;
        }
        else
        {
            /* do the real comparison */
            Datum attr1 = k1[i];
            Datum attr2 = k2[i];
            if (!DatumGetBool(FunctionCall2(&cur_bmbuild->eq_funcs[i], attr1, attr2)))
            {
                result = 1;     /* they aren't equal */
                break;
            }
        }
	}
	MemoryContextSwitchTo(old);
	return result;
}
Exemple #24
0
/* ----------------
 *		index_can_return - does index support index-only scans?
 * ----------------
 */
bool
index_can_return(Relation indexRelation)
{
	FmgrInfo   *procedure;

	RELATION_CHECKS;

	/* amcanreturn is optional; assume FALSE if not provided by AM */
	if (!RegProcedureIsValid(indexRelation->rd_am->amcanreturn))
		return false;

	GET_REL_PROCEDURE(amcanreturn);

	return DatumGetBool(FunctionCall1(procedure,
									  PointerGetDatum(indexRelation)));
}
Exemple #25
0
static void override_fields(struct PgqTriggerEvent *ev)
{
	TriggerData *tg = ev->tgdata;
	int res, i;
	char *val;

	/* no overrides */
	if (!ev->tgargs)
		return;

	for (i = 0; i < EV_NFIELDS; i++) {
		if (!ev->tgargs->query[i])
			continue;
		res = qb_execute(ev->tgargs->query[i], tg);
		if (res != SPI_OK_SELECT)
			elog(ERROR, "Override query failed");
		if (SPI_processed != 1)
			elog(ERROR, "Expect 1 row from override query, got %d", SPI_processed);

		/* special handling for EV_WHEN */
		if (i == EV_WHEN) {
			bool isnull;
			Oid oid = SPI_gettypeid(SPI_tuptable->tupdesc, 1);
			Datum res;
			if (oid != BOOLOID)
				elog(ERROR, "when= query result must be boolean, got=%u", oid);
			res = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
			if (isnull)
				elog(ERROR, "when= should not be NULL");
			if (DatumGetBool(res) == 0)
				ev->skip_event = true;
			continue;
		}

		/* normal field */
		val = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
		if (ev->field[i]) {
			pfree(ev->field[i]->data);
			pfree(ev->field[i]);
			ev->field[i] = NULL;
		}
		if (val) {
			ev->field[i] = pgq_init_varbuf();
			appendStringInfoString(ev->field[i], val);
		}
	}
}
Exemple #26
0
/*
 * Compare the tuple and slot and check if they have equal values.
 *
 * We use binary datum comparison which might return false negatives but
 * that's the best we can do here as there may be multiple notions of
 * equality for the data types and table columns don't specify which one
 * to use.
 */
static bool
tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot)
{
	Datum		values[MaxTupleAttributeNumber];
	bool		isnull[MaxTupleAttributeNumber];
	int			attrnum;

	heap_deform_tuple(tup, desc, values, isnull);

	/* Check equality of the attributes. */
	for (attrnum = 0; attrnum < desc->natts; attrnum++)
	{
		Form_pg_attribute att;
		TypeCacheEntry *typentry;

		/*
		 * If one value is NULL and other is not, then they are certainly not
		 * equal
		 */
		if (isnull[attrnum] != slot->tts_isnull[attrnum])
			return false;

		/*
		 * If both are NULL, they can be considered equal.
		 */
		if (isnull[attrnum])
			continue;

		att = TupleDescAttr(desc, attrnum);

		typentry = lookup_type_cache(att->atttypid, TYPECACHE_EQ_OPR_FINFO);
		if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_FUNCTION),
					 errmsg("could not identify an equality operator for type %s",
							format_type_be(att->atttypid))));

		if (!DatumGetBool(FunctionCall2(&typentry->eq_opr_finfo,
										values[attrnum],
										slot->tts_values[attrnum])))
			return false;
	}

	return true;
}
Exemple #27
0
/*
 * _hash_checkqual -- does the index tuple satisfy the scan conditions?
 */
bool
_hash_checkqual(IndexScanDesc scan, IndexTuple itup)
{
	/*
	 * Currently, we can't check any of the scan conditions since we do not
	 * have the original index entry value to supply to the sk_func. Always
	 * return true; we expect that hashgettuple already set the recheck flag
	 * to make the main indexscan code do it.
	 */
#ifdef NOT_USED
	TupleDesc	tupdesc = RelationGetDescr(scan->indexRelation);
	ScanKey		key = scan->keyData;
	int			scanKeySize = scan->numberOfKeys;

	while (scanKeySize > 0)
	{
		Datum		datum;
		bool		isNull;
		Datum		test;

		datum = index_getattr(itup,
							  key->sk_attno,
							  tupdesc,
							  &isNull);

		/* assume sk_func is strict */
		if (isNull)
			return false;
		if (key->sk_flags & SK_ISNULL)
			return false;

		test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
								 datum, key->sk_argument);

		if (!DatumGetBool(test))
			return false;

		key++;
		scanKeySize--;
	}
#endif

	return true;
}
Exemple #28
0
Datum
ts_match_tq(PG_FUNCTION_ARGS)
{
	TSVector	vector;
	TSQuery		query = PG_GETARG_TSQUERY(1);
	bool		res;

	vector = DatumGetTSVector(DirectFunctionCall1(to_tsvector,
												  PG_GETARG_DATUM(0)));

	res = DatumGetBool(DirectFunctionCall2(ts_match_vq,
										   TSVectorGetDatum(vector),
										   TSQueryGetDatum(query)));

	pfree(vector);
	PG_FREE_IF_COPY(query, 1);

	PG_RETURN_BOOL(res);
}
Exemple #29
0
/*
 * Turn a scalar Datum into JSON. Hand off a non-scalar datum to
 * composite_to_json or array_to_json_internal as appropriate.
 */
static inline void
datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
			  Oid typoutputfunc)
{

	char *outputstr;

	if (val == (Datum) NULL)
	{
		appendStringInfoString(result,"null");
		return;
	}

	switch (tcategory)
	{
		case TYPCATEGORY_ARRAY:
			array_to_json_internal(val, result, false);
			break;
		case TYPCATEGORY_COMPOSITE:
			composite_to_json(val, result, false);
			break;
		case TYPCATEGORY_BOOLEAN:
			if (DatumGetBool(val))
				appendStringInfoString(result,"true");
			else
				appendStringInfoString(result,"false");
			break;
		case TYPCATEGORY_NUMERIC:
			outputstr = OidOutputFunctionCall(typoutputfunc, val);
			/*
			 * Don't call escape_json here. Numeric output should
			 * be a valid JSON number and JSON numbers shouldn't
			 * be quoted.
			 */
			appendStringInfoString(result, outputstr);
			pfree(outputstr);
			break;
		default:
			outputstr = OidOutputFunctionCall(typoutputfunc, val);
			escape_json(result, outputstr);
			pfree(outputstr);
	}
}
/*
 * A helper function for calling a regular, binary logic, consistent function.
 */
static bool
directBoolConsistentFn(GinScanKey key)
{
	/*
	 * Initialize recheckCurItem in case the consistentFn doesn't know it
	 * should set it.  The safe assumption in that case is to force recheck.
	 */
	key->recheckCurItem = true;

	return DatumGetBool(FunctionCall8Coll(key->consistentFmgrInfo,
										  key->collation,
										  PointerGetDatum(key->entryRes),
										  UInt16GetDatum(key->strategy),
										  key->query,
										  UInt32GetDatum(key->nuserentries),
										  PointerGetDatum(key->extra_data),
									   PointerGetDatum(&key->recheckCurItem),
										  PointerGetDatum(key->queryValues),
									 PointerGetDatum(key->queryCategories)));
}