Ejemplo n.º 1
0
Datum
linterp_DateADT(PG_FUNCTION_ARGS)
{
	DateADT y0;
	DateADT y1;
	int32 dy;
	float8 p;
	DateADT result;
	bool eq_bounds = false;
	bool eq_abscissas = false;
	
	/* Common */
	p = linterp_abscissa(fcinfo, &eq_bounds, &eq_abscissas);
	
	/* Ordinate type specific code*/
	y0 = PG_GETARG_DATEADT(2);
	y1 = PG_GETARG_DATEADT(4);
	dy = date_diff(y1, y0);
	
	if ( eq_bounds )
	{
		if ( eq_abscissas && dy == 0 )
			result = y0;
		else 
			PG_RETURN_NULL();
	}
	else 
	{
		result = date_pl_days(y0, (int32) (p * (float8) dy));
	}

	PG_RETURN_DATEADT(result);
}
Ejemplo n.º 2
0
uint32_t ETD ( uint8_t DOB_month, 
               uint8_t DOB_day, 
               uint8_t DOB_year, 
               uint8_t month, 
               uint8_t day, 
               uint8_t year, 
               uint8_t Gender, 
               uint8_t Mode, 
               uint8_t BMI, 
               uint8_t Smoker, 
               uint8_t hour,
               uint8_t min,
               uint8_t sec)
{
  int y,i,bmi;
  uint32_t diff;
  uint32_t random;
  int32_t days;
  
  diff = date_diff(DOB_month,DOB_day,DOB_year,month,day,year);
  y = (diff * 10) / 3653;
  
  days = days_table[(Mode * 2) + Gender];
  days -= diff*10;
  bmi = BMI;
  if(bmi > 45)
    bmi = 45;
  if(bmi < 26)
    bmi = 26;
  bmi -= 26;
  if (Mode == DC_mode_optimistic) {
    days += random_days(hour,min,sec,54790);
  } else if (Mode == DC_mode_pessimistic) {
    days -= random_days(hour,min,sec,36530);
  }
  
  if(y>=20)
  {
  	  for(i=0;i<bmi_table_count[(Mode * 2) + Gender];i++)
  	  {
  	  	  if ( y < pgm_read_byte(&normal_bmi_male[bmi_table_offset[(Mode * 2) + Gender]+i][0]) )
          {
          	uint8_t temp = pgm_read_byte(&normal_bmi_male[bmi_table_offset[(Mode * 2) + Gender]+i][(bmi/2)+1]);
          	if(bmi&1)
          		temp &= 0x0F;
          	else
          		temp >>= 4;
            days -= (uint16_t)(temp * 3653);
            break;
          }
  	  }
  }
Ejemplo n.º 3
0
uint32_t date_diff ( uint8_t month1, uint8_t day1, uint8_t year1, uint8_t month2, uint8_t day2, uint8_t year2 )
{
  uint32_t diff = 0;
  int i;

  if((year2 < year1) || ((year2 == year1) && (month2 < month1)))
    return date_diff( month2, day2, year2, month1, day1, year1 ) * -1;

  if((month1 == month2) && (year1 == year2))
    return day2 - day1;
  if(year1==year2)
  {
    diff = pgm_read_byte(&day_in_month[month1-1]) - day1;
    if(month1 == 2)
      diff += is_leap_year(year1);
    for(i=month1+1;i<month2;i++)
    {
      diff+=pgm_read_byte(&day_in_month[i-1]);
      if(i==2)
        diff+=is_leap_year(year1);
    }
    diff += day2;
    return diff;
  }
  diff = pgm_read_byte(&day_in_month[month1-1]) - day1;
  if(month1 == 2)
      diff+=is_leap_year(year1);
  for(i=month1+1;i<=12;i++)
  {
    diff+=pgm_read_byte(&day_in_month[i-1]);
    if(i==2)
      diff+=is_leap_year(year1);
  }
  for(i=year1+1;i<year2;i++)
    diff+=365+is_leap_year(i);
  for(i=1;i<month2;i++)
  {
    diff+=pgm_read_byte(&day_in_month[i-1]);
    if(i==2)
      diff+=is_leap_year(year2);
  }
  diff += day2;
  return diff;
}
Ejemplo n.º 4
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;
}