Esempio n. 1
0
Datum
add_months(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	int n = PG_GETARG_INT32(1);
	int y, m, d;
	int	days;
	DateADT result;
	div_t	v;
	bool	last_day;

	j2date(day + POSTGRES_EPOCH_JDATE, &y, &m, &d);
	last_day = (d == days_of_month(y, m));

	v = div(y * 12 + m - 1 + n, 12);
	y = v.quot;
	if (y < 0)
		y += 1;	/* offset because of year 0 */
	m = v.rem + 1;

	days = days_of_month(y, m);
	if (last_day || d > days)
		d = days;

	result = date2j(y, m, d) - POSTGRES_EPOCH_JDATE;

	PG_RETURN_DATEADT (result);
}
Esempio n. 2
0
Datum
plvdate_prev_bizday (PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);

	PG_RETURN_DATEADT(ora_add_bizdays(day,-1));
}
Esempio n. 3
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);
}
Esempio n. 4
0
Datum
plvdate_add_bizdays (PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	int days = PG_GETARG_INT32(1);

	PG_RETURN_DATEADT(ora_add_bizdays(day,days));
}
Esempio n. 5
0
Datum
next_day(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	text *day_txt = PG_GETARG_TEXT_PP(1);
	const char *str = VARDATA_ANY(day_txt);
	int	len = VARSIZE_ANY_EXHDR(day_txt);
	int off;
	int d = -1;

#ifdef ENABLE_INTERNATIONALIZED_WEEKDAY
	/* Check mru_weekdays first for performance. */
	if (mru_weekdays)
	{
		if ((d = weekday_search(mru_weekdays, str, len)) >= 0)
			goto found;
		else
			mru_weekdays = NULL;
	}
#endif

	/*
	 * Oracle uses only 3 heading characters of the input.
	 * Ignore all trailing characters.
	 */
	if (len >= 3 && (d = ora_seq_prefix_search(str, ora_days, 3)) >= 0)
		goto found;

#ifdef ENABLE_INTERNATIONALIZED_WEEKDAY
	do
	{
		int		i;
		int		encoding = GetDatabaseEncoding();

		for (i = 0; i < lengthof(WEEKDAYS); i++)
		{
			if (encoding == WEEKDAYS[i].encoding)
			{
				if ((d = weekday_search(&WEEKDAYS[i], str, len)) >= 0)
				{
					mru_weekdays = &WEEKDAYS[i];
					goto found;
				}
			}
		}
	} while(0);
#endif

	CHECK_SEQ_SEARCH(-1, "DAY/Day/day");

found:
	off = d - j2day(day+POSTGRES_EPOCH_JDATE);

	PG_RETURN_DATEADT((off <= 0) ? day+off+7 : day + off);
}
Esempio n. 6
0
Datum
last_day(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	DateADT result;
	int y, m, d;
	j2date(day + POSTGRES_EPOCH_JDATE, &y, &m, &d);
	result = date2j(y, m+1, 1) - POSTGRES_EPOCH_JDATE;

	PG_RETURN_DATEADT(result - 1);
}
Esempio n. 7
0
Datum
ora_date_round(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	text *fmt = PG_GETARG_TEXT_PP(1);

	DateADT result;

	int f = ora_seq_search(VARDATA_ANY(fmt), date_fmt, VARSIZE_ANY_EXHDR(fmt));
	CHECK_SEQ_SEARCH(f, "round/trunc format string");

	result = _ora_date_round(day, f);
	PG_RETURN_DATEADT(result);
}
Esempio n. 8
0
Datum
plvdate_nearest_bizday (PG_FUNCTION_ARGS)
{
	DateADT dt = PG_GETARG_DATEADT(0);
	DateADT d1, d2, res;

	d1 = ora_add_bizdays(dt, -1);
	d2 = ora_add_bizdays(dt, 1);

	if ((dt - d1) > (d2 - dt))
		res = d2;
	else
		res = d1;

	PG_RETURN_DATEADT(res);
}
Esempio n. 9
0
/* next_day(date, integer) is not documented in Oracle manual, but ... */
Datum
next_day_by_index(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	int		idx = PG_GETARG_INT32(1);
	int		off;

	/*
	 * off is 1..7 (Sun..Sat).
	 *
	 * TODO: It should be affected by NLS_TERRITORY. For example,
	 * 1..7 should be interpreted as Mon..Sun in GERMAN.
	 */
	CHECK_SEQ_SEARCH((idx < 1 || 7 < idx) ? -1 : 0, "DAY/Day/day");

	/* j2day returns 0..6 as Sun..Sat */
	off = (idx - 1) - j2day(day+POSTGRES_EPOCH_JDATE);

	PG_RETURN_DATEADT((off <= 0) ? day+off+7 : day + off);
}