Esempio n. 1
0
Datum
linterp_Numeric(PG_FUNCTION_ARGS)
{
	float8 p;
	Numeric	y0 = PG_GETARG_NUMERIC(2);
	Numeric	y1 = PG_GETARG_NUMERIC(4);
	Numeric	result = NULL;
	bool eq_bounds = false;
	bool eq_abscissas = false;
	
	/* Common */
	p = linterp_abscissa(fcinfo, &eq_bounds, &eq_abscissas);
	
	/* Ordinate type specific code*/
	if ( eq_bounds )
	{
		if ( eq_abscissas && cmp_numerics(y0,y1) == 0 )
			result = y0;
		else
			PG_RETURN_NULL();
	}
	else 
	{
		result = numeric_li_value(p, y0, y1);
	}
	
	PG_RETURN_NUMERIC(result);
}
Datum HASHAPI_Hash_1_numeric(PG_FUNCTION_ARGS)
{
    int32 num_segs;            /* number of segments  */
	Numeric val1;	    	   /* NUMERIC 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_NUMERIC(2);
	
	d1 = NumericGetDatum(val1);
	
	/* create a CdbHash for this hash test. */
	h = makeCdbHash(num_segs, algorithm);
	
	/* init cdb hash */
	cdbhashinit(h);
	oid = NUMERICOID;
	cdbhash(h, d1, oid);
	
	/* reduce the result hash value */
	targetbucket = cdbhashreduce(h);	
	
	PG_RETURN_INT32(targetbucket); /* return target bucket (segID) */
}
Esempio n. 3
0
Datum
orafce_to_char_numeric(PG_FUNCTION_ARGS)
{
	Numeric		arg0 = PG_GETARG_NUMERIC(0);
	StringInfo	buf = makeStringInfo();
	struct lconv *lconv = PGLC_localeconv();
	char	   *p;
	char       *decimal = NULL;

	appendStringInfoString(buf, DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(arg0))));

	for (p = buf->data; *p; p++)
		if (*p == '.')
		{
			*p = lconv->decimal_point[0];
			decimal = p; /* save decimal point position for the next loop */
		}

	/* Simulate the default Oracle to_char template (TM9 - Text Minimum)
	   by removing unneeded digits after the decimal point;
	   if no digits are left, then remove the decimal point too
	*/
	for (p = buf->data + buf->len - 1; decimal && p >= decimal; p--)
	{
		if (*p == '0' || *p == lconv->decimal_point[0])
			*p = 0;
		else
			break; /* non-zero digit found, exit the loop */
	}

	PG_RETURN_TEXT_P(cstring_to_text(buf->data));
}
Esempio n. 4
0
Datum
gpupreagg_psum_numeric(PG_FUNCTION_ARGS)
{
	Assert(PG_NARGS() == 1);
	if (PG_ARGISNULL(0))
		PG_RETURN_NULL();
	PG_RETURN_NUMERIC(PG_GETARG_NUMERIC(0));
}
Esempio n. 5
0
File: pipe.c Progetto: orafce/orafce
Datum
dbms_pipe_pack_message_number(PG_FUNCTION_ARGS)
{
	Numeric num = PG_GETARG_NUMERIC(0);

	output_buffer = check_buffer(output_buffer, LOCALMSGSZ);
	pack_field(output_buffer, IT_NUMBER,
			   VARSIZE(num) - VARHDRSZ, VARDATA(num), InvalidOid);

	PG_RETURN_VOID();
}
Esempio n. 6
0
File: convert.c Progetto: 50wu/gpdb
Datum
orafce_to_char_numeric(PG_FUNCTION_ARGS)
{
	Numeric		arg0 = PG_GETARG_NUMERIC(0);
	StringInfo	buf = makeStringInfo();
	struct lconv *lconv = PGLC_localeconv();
	char	   *p;

	appendStringInfoString(buf, DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(arg0))));

	for (p = buf->data; *p; p++)
		if (*p == '.')
			*p = lconv->decimal_point[0];

	PG_RETURN_TEXT_P(cstring_to_text(buf->data));
}
Esempio n. 7
0
Datum
quantile_append_numeric_array(PG_FUNCTION_ARGS)
{
    
    struct_numeric * data;
    
    MemoryContext oldcontext;
    MemoryContext aggcontext;

    GET_AGG_CONTEXT("quantile_append_numeric_array", fcinfo, aggcontext);

    oldcontext = MemoryContextSwitchTo(aggcontext);
        
    if (PG_ARGISNULL(0)) {
        data = (struct_numeric*)palloc(sizeof(struct_numeric));
        data->elements  = (Numeric*)palloc(SLICE_SIZE*sizeof(Numeric));
        data->nelements = SLICE_SIZE;
        data->next = 0;
        
        /* read the array of quantiles */
        data->quantiles = array_to_double(fcinfo, PG_GETARG_ARRAYTYPE_P(2), &data->nquantiles);
        
    } else {
        data = (struct_numeric*)PG_GETARG_POINTER(0);
    }
    
    /* ignore NULL values */
    if (! PG_ARGISNULL(1)) {
    
        Numeric element = PG_GETARG_NUMERIC(1);
        
        if (data->next > data->nelements-1) {
            data->elements = (Numeric*)repalloc(data->elements, sizeof(Numeric)*(data->nelements + SLICE_SIZE));
            data->nelements = data->nelements + SLICE_SIZE;
        }
        
        data->elements[data->next++] = element;
        
    }
    
    MemoryContextSwitchTo(oldcontext);
    
    PG_RETURN_POINTER(data);

}
Esempio n. 8
0
Datum
_numeric_weighted_mean_intermediate(PG_FUNCTION_ARGS)
{
	WeightedMeanInternalState *state;
	Datum		value,
				weight,
				temp_total,
				old_sum,
				old_weight;
	MemoryContext aggcontext,
				oldcontext;

	if (!AggCheckCallContext(fcinfo, &aggcontext))
		/* cannot be called directly because of internal-type argument */
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("_numeric_weighted_mean_intermediate called in non-aggregate context")));

	if (PG_ARGISNULL(0))
	{
		oldcontext = MemoryContextSwitchTo(aggcontext);
		state = (WeightedMeanInternalState *) palloc(sizeof(WeightedMeanInternalState));
		state->running_sum = make_numeric(0);
		state->running_weight = make_numeric(0);
		MemoryContextSwitchTo(oldcontext);
	}
	else
		state = (WeightedMeanInternalState *) PG_GETARG_POINTER(0);

	/*
	 * We're non-strict, so we MUST check args for nullity ourselves before
	 * using them.  To preserve the behaviour of null inputs, we skip updating
	 * on them.
	 */

	if (PG_ARGISNULL(1) || PG_ARGISNULL(2))
		PG_RETURN_POINTER(state);

	/*
	 * We fetch and process the input in the shortlived calling context to
	 * avoid leaking memory in aggcontext per cycle. We force the input to be
	 * detoasted here, too, in the shortlived context. (PG_GETARG_DATUM does
	 * not detoast, but PG_GETARG_NUMERIC does.)
	 */

	value = NumericGetDatum(PG_GETARG_NUMERIC(1));
	weight = NumericGetDatum(PG_GETARG_NUMERIC(2));
	temp_total = DirectFunctionCall2(numeric_mul, value, weight);

	/*
	 * The new running totals must be allocated in the long-lived context.  We
	 * rely on the numeric_* functions to clean up after themselves (which they
	 * currently do, but only if the input is already detoasted); we could play
	 * safe and copy only the final results into aggcontext, but this turns out
	 * to have a measurable performance hit.
	 */

	oldcontext = MemoryContextSwitchTo(aggcontext);

	old_sum = state->running_sum;
	old_weight = state->running_weight;

	state->running_sum = DirectFunctionCall2(numeric_add,
											 state->running_sum, temp_total);

	state->running_weight = DirectFunctionCall2(numeric_add,
												state->running_weight, weight);

	pfree(DatumGetPointer(old_sum));
	pfree(DatumGetPointer(old_weight));

	MemoryContextSwitchTo(oldcontext);

	PG_RETURN_POINTER(state);
}
Esempio n. 9
0
Datum
_numeric_weighted_stddev_samp_intermediate(PG_FUNCTION_ARGS)
{
	WeightedStddevSampInternalState *state;
	Datum		value,
				weight,
				old_s_0,
				old_s_1,
				old_s_2,
				w_v,
				w_v2;
	MemoryContext aggcontext,
				  oldcontext;

	if (!AggCheckCallContext(fcinfo, &aggcontext))
		/* cannot be called directly because of internal-type argument */
		elog(ERROR, "_weighted_stddev_samp_intermediate called in non-aggregate context");

	if (PG_ARGISNULL(0))
	{
		oldcontext = MemoryContextSwitchTo(aggcontext);
		state = (WeightedStddevSampInternalState *) palloc(sizeof(WeightedStddevSampInternalState));
		state->s_2 = make_numeric(0);
		state->s_1 = make_numeric(0);
		state->s_0 = make_numeric(0);
		state->zero = make_numeric(0);
		state->n_prime = 0;
		MemoryContextSwitchTo(oldcontext);
	}
	else
		state = (WeightedStddevSampInternalState *) PG_GETARG_POINTER(0);

	/*
	 * We're non-strict, so we MUST check args for nullity ourselves before
	 * using them.  To preserve the behaviour of null inputs, we skip updating
	 * on them.
	 */

	if (PG_ARGISNULL(1) || PG_ARGISNULL(2))
		PG_RETURN_POINTER(state);

	/*
	 * We fetch and process the input in the shortlived calling context to
	 * avoid leaking memory in aggcontext per cycle. We force the input to be
	 * detoasted here, too, in the shortlived context. (PG_GETARG_DATUM does
	 * not detoast, but PG_GETARG_NUMERIC does.)
	 */

	value = NumericGetDatum(PG_GETARG_NUMERIC(1));
	weight = NumericGetDatum(PG_GETARG_NUMERIC(2));

	/*
	 * We also skip updating when the weight is zero.
	 */
	if (DatumGetBool(DirectFunctionCall2(numeric_eq, weight, state->zero)))
		PG_RETURN_POINTER(state);

	/*
	 * Compute intermediate values w*v and w*(v^2) in the short-lived context
	 */

	w_v = DirectFunctionCall2(numeric_mul, weight, value);
	w_v2 = DirectFunctionCall2(numeric_mul, w_v, value);

	/*
	 * The new running totals must be allocated in the long-lived context.  We
	 * rely on the numeric_* functions to clean up after themselves (which they
	 * currently do, but only if the input is already detoasted); we could play
	 * safe and copy only the final results into aggcontext, but this turns out
	 * to have a measurable performance hit.
	 */

	oldcontext = MemoryContextSwitchTo(aggcontext);

	old_s_2 = state->s_2;
	old_s_1 = state->s_1;
	old_s_0 = state->s_0;

	state->s_0 = DirectFunctionCall2(numeric_add, old_s_0, weight);
	state->s_1 = DirectFunctionCall2(numeric_add, old_s_1, w_v);
	state->s_2 = DirectFunctionCall2(numeric_add, old_s_2, w_v2);

	state->n_prime += 1;

	pfree(DatumGetPointer(old_s_2));
	pfree(DatumGetPointer(old_s_1));
	pfree(DatumGetPointer(old_s_0));

	MemoryContextSwitchTo(oldcontext);

	PG_RETURN_POINTER(state);
}
Esempio n. 10
0
/* 
 * 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;
}