sqlparser/language.cpp
// num UNITS DAY | SECOND etc. operator in Informix (interval in days, seconds etc.)
// num DAY | SECOND etc. in DB2
num UNITS DAY | SECOND etc. operator in Informix (interval in days, seconds etc.)
num DAY | SECOND etc. in DB2
num UNITS DAY | SECOND etc . operator in Informix ( interval in days seconds etc . ) num DAY | SECOND etc . in DB2
bool SqlParser::ParseUnitsOperator(Token *first)
{
	if(first == NULL || Source(SQL_DB2, SQL_INFORMIX) == false)
		return false;
	Token *first_end = GetLastToken();
	Token *units = GetNext("UNITS", L"UNITS", 5);
	if(_source == SQL_INFORMIX && units == NULL)
		return false;
	Token *month = GetNext("MONTH", L"MONTH", 5);
	Token *months = NULL;
	if(month == NULL)
		months = GetNext("MONTHS", L"MONTHS", 6);
	Token *field = Nvl(month, months);
	Token *day = NULL;
	Token *days = NULL;
	Token *minute = NULL;
	Token *minutes = NULL;
	Token *second = NULL;
	if(field == NULL)
	{
		day = GetNext("DAY", L"DAY", 3);
		if(day == NULL)
			days = GetNext("DAYS", L"DAYS", 4);
		field = Nvl(day, days);
	}
	if(field == NULL)
	{
		minute = GetNext("MINUTE", L"MINUTE", 6);
		if(minute == NULL)
			minutes = GetNext("MINUTES", L"MINUTES", 7);
		field = Nvl(minute, minutes);
	}
	if(field == NULL)
	{
		second = GetNextWordToken("SECOND", L"SECOND", 6);
		field = second;
	}
	if(field == NULL)
		return false;
	bool first_num = first->IsNumeric();
	if(_target == SQL_ORACLE)
	{
		if(first_num == true)
		{
			Prepend(first, "INTERVAL '", L"INTERVAL '", 10, field);
			AppendNoFormat(first, "'", L"'", 1);
		}
		else
		{
			Prepend(first, "NUMTODSINTERVAL(", L"NUMTODSINTERVAL(", 16, field);
			AppendNoFormat(first_end, ",", L",", 1);
			PrependNoFormat(field, "'", L"'", 1);
			AppendNoFormat(field, "')", L"')", 2);
		}
		if(days != NULL)
			Token::Change(days, "DAY", L"DAY", 3);
		if(minutes != NULL)
			Token::Change(minutes, "MINUTE", L"MINUTE", 6);
		Token::Remove(units);
	}
	else
	if(_target == SQL_SQL_SERVER)
		Token::Remove(field);
	else
	if(_target == SQL_POSTGRESQL)
	{
		if(first_num == true)
		{
			Prepend(first, "INTERVAL '", L"INTERVAL '", 10, field);
			AppendNoFormat(first, "'", L"'", 1);
			Token::Remove(units);
		}
		else
			Token::Change(units, "* INTERVAL '1'", L"* INTERVAL '1'", 14);
	}
	first->data_type = TOKEN_DT_INTERVAL;
	if(day != NULL || days != NULL)
		first->data_subtype = TOKEN_DT2_INTVL_DAY;
	else
	if(month != NULL || months != NULL)
		first->data_subtype = TOKEN_DT2_INTVL_MON;
	else
	if(minute != NULL || minutes != NULL)
		first->data_subtype = TOKEN_DT2_INTVL_MIN;
	else
	if(second != NULL)
		first->data_subtype = TOKEN_DT2_INTVL_SEC;
	return true;
}
bool SqlParser :: ParseUnitsOperator ( Token * first ) { if ( first == NULL || Source ( SQL_DB2 , SQL_INFORMIX ) == false ) return false ; Token * first_end = GetLastToken ( ) ; Token * units = GetNext ( " " , L" " , 5 ) ; if ( _source == SQL_INFORMIX && units == NULL ) return false ; Token * month = GetNext ( " " , L" " , 5 ) ; Token * months = NULL ; if ( month == NULL ) months = GetNext ( " " , L" " , 6 ) ; Token * field = Nvl ( month , months ) ; Token * day = NULL ; Token * days = NULL ; Token * minute = NULL ; Token * minutes = NULL ; Token * second = NULL ; if ( field == NULL ) { day = GetNext ( " " , L" " , 3 ) ; if ( day == NULL ) days = GetNext ( " " , L" " , 4 ) ; field = Nvl ( day , days ) ; } if ( field == NULL ) { minute = GetNext ( " " , L" " , 6 ) ; if ( minute == NULL ) minutes = GetNext ( " " , L" " , 7 ) ; field = Nvl ( minute , minutes ) ; } if ( field == NULL ) { second = GetNextWordToken ( " " , L" " , 6 ) ; field = second ; } if ( field == NULL ) return false ; bool first_num = first -> IsNumeric ( ) ; if ( _target == SQL_ORACLE ) { if ( first_num == true ) { Prepend ( first , " " , L" " , 10 , field ) ; AppendNoFormat ( first , " " , L" " , 1 ) ; } else { Prepend ( first , " " , L" " , 16 , field ) ; AppendNoFormat ( first_end , " " , L" " , 1 ) ; PrependNoFormat ( field , " " , L" " , 1 ) ; AppendNoFormat ( field , " " , L" " , 2 ) ; } if ( days != NULL ) Token :: Change ( days , " " , L" " , 3 ) ; if ( minutes != NULL ) Token :: Change ( minutes , " " , L" " , 6 ) ; Token :: Remove ( units ) ; } else if ( _target == SQL_SQL_SERVER ) Token :: Remove ( field ) ; else if ( _target == SQL_POSTGRESQL ) { if ( first_num == true ) { Prepend ( first , " " , L" " , 10 , field ) ; AppendNoFormat ( first , " " , L" " , 1 ) ; Token :: Remove ( units ) ; } else Token :: Change ( units , " " , L" " , 14 ) ; } first -> data_type = TOKEN_DT_INTERVAL ; if ( day != NULL || days != NULL ) first -> data_subtype = TOKEN_DT2_INTVL_DAY ; else if ( month != NULL || months != NULL ) first -> data_subtype = TOKEN_DT2_INTVL_MON ; else if ( minute != NULL || minutes != NULL ) first -> data_subtype = TOKEN_DT2_INTVL_MIN ; else if ( second != NULL ) first -> data_subtype = TOKEN_DT2_INTVL_SEC ; return true ; }
num UNITS DAY | SECOND etc.
num UNITS DAY | SECOND etc .
// UNITS can be used with a number constant and expression (!) in Informix // MONTHS in DB2 // Not an interval field // INTERVAL 'num' DAY, or NUMTODSINTERVAL(var, 'DAY') in Oracle // Number constant // Variable or expression // Oracle allow only singular form DAY, not DAYS i.e // For SQL Server, remove field keyword as it will replaced by DATEADD for +/- expressions // INTERVAL 'num' units, or var * INTERVAL '1' units in PostgreSQL // Number constant // Variable or expression