예제 #1
0
Datum
tstz_dist(PG_FUNCTION_ARGS)
{
	TimestampTz a = PG_GETARG_TIMESTAMPTZ(0);
	TimestampTz b = PG_GETARG_TIMESTAMPTZ(1);
	Interval   *r;

	if (TIMESTAMP_NOT_FINITE(a) || TIMESTAMP_NOT_FINITE(b))
	{
		Interval   *p = palloc(sizeof(Interval));

		p->day = INT_MAX;
		p->month = INT_MAX;
#ifdef HAVE_INT64_TIMESTAMP
		p->time = INT64CONST(0x7FFFFFFFFFFFFFFF);
#else
		p->time = DBL_MAX;
#endif
		PG_RETURN_INTERVAL_P(p);
	}

	r = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
											  PG_GETARG_DATUM(0),
											  PG_GETARG_DATUM(1)));
	PG_RETURN_INTERVAL_P(abs_interval(r));
}
예제 #2
0
파일: datefce.c 프로젝트: vinpokale/orafce
Datum
ora_timestamptz_round(PG_FUNCTION_ARGS)
{
	TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
	TimestampTz result;
	text *fmt = PG_GETARG_TEXT_PP(1);
	int tz;
	fsec_t fsec;
	struct pg_tm tt, *tm = &tt;
	const char *tzn;
	bool redotz = false;

	if (TIMESTAMP_NOT_FINITE(timestamp))
		PG_RETURN_TIMESTAMPTZ(timestamp);

	if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
		ereport(ERROR,
					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
					 errmsg("timestamp out of range")));

	tm_round(tm, fmt, &redotz);

	if (redotz)
		tz = DetermineTimeZoneOffset(tm, get_session_timezone(fcinfo));

	if (tm2timestamp(tm, fsec, &tz, &result) != 0)
		ereport(ERROR,
				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
				 errmsg("timestamp out of range")));

	PG_RETURN_TIMESTAMPTZ(result);
}
Datum HASHAPI_Hash_1_timestamptz(PG_FUNCTION_ARGS)
{
    int32 num_segs;            /* number of segments  */
	TimestampTz val1;        	   /* varchar value		  */
    unsigned int targetbucket; /* 0-based             */
	int16 algorithm;  /* hashing algorithm   */
	Datum d1;
	Oid oid;

	/* Get number of segments */
    num_segs = PG_GETARG_INT32(0);
    
	/* Get hashing algoriithm */
	algorithm = PG_GETARG_INT16(1);
	
	/* Get the value to hash */
	val1 = PG_GETARG_TIMESTAMPTZ(2);
	
	d1 = TimestampTzGetDatum(val1);
	
	/* create a CdbHash for this hash test. */
	h = makeCdbHash(num_segs, algorithm);
	
	/* init cdb hash */
	cdbhashinit(h);
	oid = TIMESTAMPTZOID;
	cdbhash(h, d1, oid);
	
	/* reduce the result hash value */
	targetbucket = cdbhashreduce(h);	
	
	PG_RETURN_INT32(targetbucket); /* return target bucket (segID) */
}
예제 #4
0
파일: pipe.c 프로젝트: orafce/orafce
Datum
dbms_pipe_pack_message_timestamp(PG_FUNCTION_ARGS)
{
	TimestampTz dt = PG_GETARG_TIMESTAMPTZ(0);

	output_buffer = check_buffer(output_buffer, LOCALMSGSZ);
	pack_field(output_buffer, IT_TIMESTAMPTZ,
			   sizeof(dt), &dt, InvalidOid);

	PG_RETURN_VOID();
}
예제 #5
0
Datum
gbt_tstz_distance(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	TimestampTz query = PG_GETARG_TIMESTAMPTZ(1);

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

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

	PG_RETURN_FLOAT8(
			  gbt_num_distance(&key, (void *) &qqq, GIST_LEAF(entry), &tinfo)
		);
}
예제 #6
0
/*
 * assign_distributed_transaction_id updates the shared memory allocated for this backend
 * and sets initiatorNodeIdentifier, transactionNumber, timestamp fields with the given
 * inputs. Also, the function sets the database id and process id via the information that
 * Postgres provides.
 *
 * This function is only intended for internal use for managing distributed transactions.
 * Users should not use this function for any purpose.
 */
Datum
assign_distributed_transaction_id(PG_FUNCTION_ARGS)
{
	CheckCitusVersion(ERROR);

	/* MyBackendData should always be avaliable, just out of paranoia */
	if (!MyBackendData)
	{
		ereport(ERROR, (errmsg("backend is not ready for distributed transactions")));
	}

	/*
	 * Note that we don't need to lock shared memory (i.e., LockBackendSharedMemory()) here
	 * since this function is executed after AssignDistributedTransactionId() issued on the
	 * initiator node, which already takes the required lock to enforce the consistency.
	 */

	SpinLockAcquire(&MyBackendData->mutex);

	/* if an id is already assigned, release the lock and error */
	if (MyBackendData->transactionId.transactionNumber != 0)
	{
		SpinLockRelease(&MyBackendData->mutex);

		ereport(ERROR, (errmsg("the backend has already been assigned a "
							   "transaction id")));
	}

	MyBackendData->databaseId = MyDatabaseId;

	MyBackendData->transactionId.initiatorNodeIdentifier = PG_GETARG_INT32(0);
	MyBackendData->transactionId.transactionNumber = PG_GETARG_INT64(1);
	MyBackendData->transactionId.timestamp = PG_GETARG_TIMESTAMPTZ(2);
	MyBackendData->transactionId.transactionOriginator = false;

	SpinLockRelease(&MyBackendData->mutex);

	PG_RETURN_VOID();
}
예제 #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)
		);
}
예제 #8
0
파일: interpolate.c 프로젝트: hsyuan/gpdb
/* 
 * linterp_abscissa
 *
 * Common code that checks arguments.  The result is a floating point value
 * representing what fraction of the distance x lies along the interval from
 * x0 to x1.  It can be negative or greater than one (extrapolation) though
 * this isn't the intended use.  If x0 == x1, then the fraction is not
 * determined and the function returns 0 and sets *notnull false.  In all
 * other cases (except error exits) *notnull is set to true.  An additional
 * flag indicates whether the abscissa value is equal to the lower boundary
 * value.
 */
static float8
linterp_abscissa(PG_FUNCTION_ARGS, bool *p_eq_bounds, bool *p_eq_abscissas)
{
	Oid         x_type;
	Oid         x0_type;
	Oid         x1_type;
	Oid			y0_type;
	Oid			y1_type;
	float8		p = 0;
	bool		eq_bounds = false;
	bool		eq_abscissas = false;
	
	/* The abscissa (x) arguments are nominally declared anyelement.
	 * All the type checking is up to us.  We insist that the types
	 * are exactly alike.  Explicit casts may be needed.
	 */
	x_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
	x0_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
	x1_type = get_fn_expr_argtype(fcinfo->flinfo, 3);

	if (!OidIsValid(x_type)||!OidIsValid(x0_type)||!OidIsValid(x1_type))
	{
		elog(ERROR, "could not determine argument data types");
	}
	
	if ( x_type!=x0_type || x_type!=x1_type )
	{
		elog(ERROR, "abscissa types unequal");
	}
	
	/* The ordinate (y) arguments are specifically declared in the SQL
	 * function declaration.  Here we just check and insist they are
	 * identical.
	 */
	y0_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
	y1_type = get_fn_expr_argtype(fcinfo->flinfo, 4);

	if ( y0_type !=  y1_type )
	{
		elog(ERROR, "mismatched ordinate types");
	}

	switch (x_type)
	{
	case INT8OID:
		{
			float8 x = (float8)PG_GETARG_INT64(0);
			float8 x0 = (float8)PG_GETARG_INT64(1);
			float8 x1 = (float8)PG_GETARG_INT64(3);
			if ( x1 == x0 )
			{
				eq_bounds = true;
				eq_abscissas = ( x == x0 );
			}
			else
				p = (x-x0)/(x1-x0);
		}
		break;
	case INT4OID:
		{
			float8 x = (float8)PG_GETARG_INT32(0);
			float8 x0 = (float8)PG_GETARG_INT32(1);
			float8 x1 = (float8)PG_GETARG_INT32(3);
			if ( x1 == x0 )
			{
				eq_bounds = true;
				eq_abscissas = ( x == x0 );
			}
			else
				p = (x-x0)/(x1-x0);
		}
		break;
	case INT2OID:
		{
			float8 x = (float8)PG_GETARG_INT16(0);
			float8 x0 = (float8)PG_GETARG_INT16(1);
			float8 x1 = (float8)PG_GETARG_INT16(3);
			
			if ( x1 == x0 )
			{
				eq_bounds = true;
				eq_abscissas = ( x == x0 );
			}
			else
				p = (x-x0)/(x1-x0);
		}
		break;
	case FLOAT4OID:
		{
			float8 x = (float8)PG_GETARG_FLOAT4(0);
			float8 x0 = (float8)PG_GETARG_FLOAT4(1);
			float8 x1 = (float8)PG_GETARG_FLOAT4(3);
			
			if ( x1 == x0 )
			{
				eq_bounds = true;
				eq_abscissas = ( x == x0 );
			}
			else
				p = (x-x0)/(x1-x0);
		}
		break;
	case FLOAT8OID:
		{
			float8 x = PG_GETARG_FLOAT8(0);
			float8 x0 = PG_GETARG_FLOAT8(1);
			float8 x1 = PG_GETARG_FLOAT8(3);
			
			if ( x1 == x0 )
			{
				eq_bounds = true;
				eq_abscissas = ( x == x0 );
			}
			else
				p = (x-x0)/(x1-x0);
		}
		break;
	case DATEOID:
		{
			DateADT x = PG_GETARG_DATEADT(0);
			DateADT x0 = PG_GETARG_DATEADT(1);
			DateADT x1 = PG_GETARG_DATEADT(3);
			int32 x_x0 = date_diff(x, x0);
			int32 x1_x0 = date_diff(x1, x0);
			
			if ( x1 == x0 )
			{
				eq_bounds = true;
				eq_abscissas = ( x_x0 == 0 );
			}
			else
				p = ((float8)x_x0)/((float8)x1_x0);
		}
		break;
	case TIMEOID:
		{
			TimeADT x = PG_GETARG_TIMEADT(0);
			TimeADT x0 = PG_GETARG_TIMEADT(1);
			TimeADT x1 = PG_GETARG_TIMEADT(3);
			
			p = time_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas);
		}
		break;
	case TIMESTAMPOID:
		{
			Timestamp x = PG_GETARG_TIMESTAMP(0);
			Timestamp x0 = PG_GETARG_TIMESTAMP(1);
			Timestamp x1 = PG_GETARG_TIMESTAMP(3);
			
			p = timestamp_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas);
		}
		break;
	case TIMESTAMPTZOID:
		{
			TimestampTz x = PG_GETARG_TIMESTAMPTZ(0);
			TimestampTz x0 = PG_GETARG_TIMESTAMPTZ(1);
			TimestampTz x1 = PG_GETARG_TIMESTAMPTZ(3);
			
			p = timestamptz_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas);
		}
		break;
	case INTERVALOID:
		{
			Interval * x = PG_GETARG_INTERVAL_P(0);
			Interval * x0 = PG_GETARG_INTERVAL_P(1);
			Interval * x1 = PG_GETARG_INTERVAL_P(3);
			
			p = interval_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas);
		}
		break;
	case NUMERICOID:    
		{
			Numeric x = PG_GETARG_NUMERIC(0);
			Numeric x0 = PG_GETARG_NUMERIC(1);
			Numeric x1 = PG_GETARG_NUMERIC(3);
			
			p = numeric_li_fraction(x, x0, x1, &eq_bounds, &eq_abscissas);
		}
		break;
	default:
		elog(ERROR, "abscissa type not supported");
	}
	
	if ( p_eq_bounds )
		*p_eq_bounds = eq_bounds;
	
	if ( p_eq_abscissas )
		*p_eq_abscissas = eq_abscissas;
	
	return p;
}