Beispiel #1
0
// Append the token with the specified value
Token* SqlParser::Append(Token *token, const char *str, const wchar_t *wstr, int len, Token *format)
{
	if(token == NULL)
		return NULL;

	Token *append = new Token();

	if(format == NULL)
		*append = *token;
	else
		*append = *format;

	append->prev = NULL;
	append->next = NULL;

	append->t_str = NULL;
	append->t_wstr = NULL;
	append->t_len = 0;
	
	// If token starts with newline, add the same number of spaces before appended token
	if(str != NULL && str[0] == '\n')
	{
		// Add newline token first
		Token newline;

#ifdef WIN32
		newline.type = TOKEN_SYMBOL;
		newline.chr = '\r';
		
		AppendCopy(token, &newline);
#endif

		newline.type = TOKEN_SYMBOL;
		newline.chr = '\n';
		
		AppendCopy(token, &newline);

		Token *prev = (format != NULL) ? format->prev : token->prev;

		// Copy all blankes 
		while(prev != NULL && (prev->Compare(' ', L' ') == true || prev->Compare('\t', L'\t') == true))
		{
			AppendCopy(token, prev);
			prev = prev->prev;
		}

		// Skip new line in the token
		Token::Change(append, str + 1, wstr + 1, len - 1);
	}
	else
		Token::Change(append, str, wstr, len);

	Append(token, append);

	return append;
}
Beispiel #2
0
// MODIFIED BY option in EXPORT command
bool SqlParser::Db2ParseModifiedByOptions(Token **colsep_out)
{
	bool exists = false;

	Token *start = NULL;

	// Options
	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		if(start == NULL)
			start = next;

		// COLDELx where x is a single characater column delimiter
		if(next->Compare("COLDEL", L"COLDEL", 0, 6) == true)
		{
			Token *del = NULL;

			// x is a special punctuation character it is selected as a separate token
			if(next->len == 6)
			{
				del = GetNextToken();

				if(colsep_out != NULL)
					*colsep_out = del;
			}

			exists = true;
		}
		else
		// NOCHARDEL
		if(next->Compare("NOCHARDEL", L"NOCHARDEL", 9) == true)
		{
			exists = true;
		}
		// Unknown option
		else
		{
			PushBack(next);
			break;
		}
	}

	if(exists == true)
	{
		// Remove options
		if(_target == SQL_ORACLE)
			Token::Remove(start, GetLastToken());
	}

	return exists;
}
Beispiel #3
0
// DB2 FETCH FIRST n ROWS ONLY clause in SELECT statement
bool SqlParser::ParseDb2FetchFirstRowOnly(Token *fetch, Token **rowlimit_soptions, int *rowlimit)
{
	if(fetch == NULL || Token::Compare(fetch, "FETCH", L"FETCH", 5) == false)
		return false;

	Token *first = GetNextWordToken("FIRST", L"FIRST", 5);

	if(first == NULL)
		return false;

	// Optional number of rows, meaning 1 row if skipped
	Token *num = GetNextToken();
	Token *rows = NULL;

	if(num == NULL)
		return false;

	// Check if num already points to ROW or ROWS
	if(num->Compare("ROW", L"ROW", 3) == true || num->Compare("ROWS", L"ROWS", 4) == true)
	{
		rows = num;
		num = NULL;
	}

	// ROWS or ROW
	if(rows == NULL)
		rows = GetNextToken();

	Token *only = GetNextWordToken("ONLY", L"ONLY", 4);

	if(only == NULL)
		return false;

	// Set rowlimit to output
	if(num == NULL && rowlimit != NULL)
		*rowlimit = 1;
	else
	if(num != NULL && rowlimit_soptions != NULL)
		*rowlimit_soptions = num;

	// ROWNUM is used in Oracle
	if(_target == SQL_ORACLE)
	{
		Token::Remove(fetch);
		Token::Remove(first, only);
	}

	return true;
}
Beispiel #4
0
// In DB2 a number can be followed by size specifier K, M or G
Token* SqlParser::Db2SizeSpecifier()
{
	Token *spec = GetNextToken();

	if(spec == NULL)
		return NULL;

	if(spec->Compare("K", L"K", 1) == false && spec->Compare("M", L"M", 1) == false &&
		spec->Compare("G", L"G", 1) == false)
	{
		PushBack(spec);
		return NULL;
	}

	return spec;
}
Beispiel #5
0
// Sybase ADS EXECUTE PROCEDURE statement 
bool SqlParser::ParseSybaseExecuteProcedureStatement(Token * /*execute*/)
{
	Token *procedure = TOKEN_GETNEXTW("PROCEDURE");

	if(procedure == NULL)
		return false;

	// Procedure name
	Token *name = GetNextIdentToken();

	if(name == NULL)
		return false;

	// List of parameters, empty () when there are no params
	Token *open = TOKEN_GETNEXT('(');
	Token *close = NULL;

	if(open != NULL)
	{
		while(true)
		{
			Token *param = GetNextToken();

			if(param == NULL)
				break;

			// () can be specified
			if(param->Compare(')', L')') == true)
			{
				PushBack(param);
				break;
			}

			ParseExpression(param);

			// Next parameter
			Token *comma = TOKEN_GETNEXT(',');

			if(comma == NULL)
				break;
		}

		close = TOKEN_GETNEXT(')');
	}

	// SQL Server does not allow ( and )
	if(_target == SQL_SQL_SERVER)
	{
		Token::Remove(open);
		Token::Remove(close);
	}

	if(_target != SQL_SYBASE_ADS)
		Token::Remove(procedure);

	return true;
}
Beispiel #6
0
// Prepend the token with the specified value
Token* SqlParser::Prepend(Token *token, const char *str, const wchar_t *wstr, int len, Token *format)
{
	if(token == NULL)
		return NULL;

	Token *prepend = new Token();

	// Define how to format the token
	if(format == NULL)
		*prepend = *token;
	else
		*prepend = *format;

	prepend->prev = NULL;
	prepend->next = NULL;
	prepend->t_str = NULL;
	prepend->t_wstr = NULL;
	prepend->t_len = 0;

	prepend->flags = TOKEN_INSERTED;

	Token::Change(prepend, str, wstr, len);
	Prepend(token, prepend);

	// If token ends with newline, add the same number of spaces after prepended token
	if(str != NULL && str[len - 1] == '\n')
	{
		Token *prev = token->prev;

		// Skip previously appended tokens
		while(prev != NULL && prev->flags & TOKEN_INSERTED)
			prev = prev->prev;

		// Copy all blanks and tabs before appended token after new line
		while(prev != NULL && (prev->Compare(' ', L' ') == true || prev->Compare('\t', L'\t') == true))
		{
			AppendCopy(prepend, prev);
			prev = prev->prev;
		}
	}

	return prepend;
}
Beispiel #7
0
// Parse Teradata CREATE TABLE storage clause
bool SqlParser::ParseTeradataStorageClause(int obj_scope, Token *last_colname, Token *last_colend)
{
	bool exists = false;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// UNIQUE PRIMARY INDEX hash partitioning clause
		if(next->Compare("UNIQUE", L"UNIQUE", 6) == true)
		{
			Token *primary = GetNext("PRIMARY", L"PRIMARY", 7);

			if(primary != NULL)
				ParseTeradataPrimaryIndex(next, primary, obj_scope, last_colname, last_colend);

			exists = true;
			continue;
		}
		else
		// PRIMARY INDEX hash partitioning clause
		if(next->Compare("PRIMARY", L"PRIMARY", 7) == true)
		{
			ParseTeradataPrimaryIndex(NULL, next, obj_scope, last_colname, last_colend);

			exists = true;
			continue;
		}

		// Not a storage clause
		PushBack(next);
		break;
	}

	return exists;
}
Beispiel #8
0
// Get next token and make sure it contains the specified word
Token* SqlParser::GetNextWordToken(const char *str, const wchar_t *wstr, int len)
{
	Token *token = GetNextToken();

	if(token == NULL)
		return NULL;

	if(token->Compare(str, wstr, len) == true)
		return token;
	else
		PushBack(token);

	return NULL;
}
Beispiel #9
0
// Get the next token and make sure if contains the specified char
Token* SqlParser::GetNextCharToken(const char ch, const wchar_t wch)
{
	Token *token = GetNextToken();

	if(token == NULL)
		return NULL;

	if(token->Compare(ch, wch) == true)
		return token;
	else
		PushBack(token);

	return NULL;
}
Beispiel #10
0
// Parse SQL Server CREATE TABLE storage clause
bool SqlParser::ParseSqlServerStorageClause()
{
	bool exists = false;

	while(true)
	{
		Token *next = GetNext();

		if(next == NULL)
			break;

		// ON filegroup_name
		if(next->Compare("ON", L"ON", 2) == true)
		{
			// File group name
			Token *name = GetNext();
			
			if(_target != SQL_SQL_SERVER)
			{
				// Remove clause if it is the default PRIMARY file group
				if(Token::Compare(name, "PRIMARY", L"PRIMARY", 7) == true ||
					Token::Compare(name, "[PRIMARY]", L"[PRIMARY]", 9) == true)
				{
					Token::Remove(next, name);
				}
			}

			exists = true;
		}
		else
		{
			PushBack(next);
			break;
		}
	}

	return exists;
}
Beispiel #11
0
// Set Removed flag for the token
void Token::Remove(Token *token, bool remove_spaces_before)
{
	if(token == NULL)
		return;

	token->flags |= TOKEN_REMOVED;

	Token *prev = token->prev;
	Token *next = token->next;

	if(prev == NULL)
		return;

	if(remove_spaces_before == true)
	{
		// Remove spaces token before the removed word (recursively), but only if there is a blank or ) , ;
		// after removed token (otherwise tokens can be merged)
		if(prev->Compare(' ', L' ') == true || prev->Compare('\t', L'\t') == true)
		{
			if(next != NULL)
			{
				if(next->IsBlank() == true || next->Compare(')', L')') == true || 
					next->Compare(',', L',') == true || next->Compare(';', L';') == true)
					Remove(prev);
			}
			else
			// Next token can be not selected yet
			if(token->next_start != NULL && token->remain_size > 1)
			{
				const char *cur = token->next_start;

				if(*cur == ' ' || *cur == ')' || *cur == ',' || *cur == ';')
					Remove(prev);
			}
		}
	}
	// In case cases better to remove spaces after: "SET var = 1" to "var := 1" when SET is removed 
	else
	{
		if(next != NULL && next->Compare(' ', L' ') == true)
			Remove(next);
	}
}
Beispiel #12
0
// DB2 CREATE INDEX storage options
bool SqlParser::ParseDb2CreateIndexOptions()
{
	bool exists = false;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// DB2 z/OS USING STOGROUP
		if(next->Compare("USING", L"USING", 5) == true)
		{
			Token *stogroup = GetNextWordToken("STOGROUP", L"STOGROUP", 8);

			if(stogroup != NULL)
				ParseDb2StogroupClause(NULL, next, stogroup, SQL_SCOPE_INDEX);

			exists = true;
			continue;
		}
		else
		// DB2 CLUSTER option
		if(next->Compare("CLUSTER", L"CLUSTER", 7) == true)
		{
			if(_target != SQL_DB2)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// DB2 for z/OS NOT CLUSTER, NOT PADDED 
		if(next->Compare("NOT", L"NOT", 3) == true)
		{
			Token *cluster = GetNextWordToken("CLUSTER", L"CLUSTER", 7);
			Token *padded = NULL;

			if(cluster == NULL)
				padded = GetNextWordToken("PADDED", L"PADDED", 6);

			if(cluster != NULL || padded != NULL)
			{
				if(_target != SQL_DB2)
				{
					if(cluster != NULL)
						Token::Remove(next, cluster);
					else
					if(padded != NULL)
						Token::Remove(next, padded);
				}

				exists = true;
				continue;
			}
		}
		else
		// DB2 COMPRESS NO | YES option
		if(next->Compare("COMPRESS", L"COMPRESS", 8) == true)
		{
			Token *value = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 ALLOW REVERSE SCAN
		if(next->Compare("ALLOW", L"ALLOW", 5) == true)
		{
			/*Token *reverse */ (void) GetNextWordToken("REVERSE", L"REVERSE", 7);
			Token *scan = GetNextWordToken("SCAN", L"SCAN", 4);
			
			if(_target != SQL_DB2)
				Token::Remove(next, scan);

			exists = true;
			continue;
		}
		else
		// DB2 PCTFREE
		if(next->Compare("PCTFREE", L"PCTFREE", 7) == true)
		{
			Token *value = GetNextToken();

			int int_value = (value != NULL) ? value->GetInt() : 0;
			
			// WITH (FILLFACTOR = 100 - val) in Greenplum
			if(_target == SQL_GREENPLUM)
			{
				Token::Change(next, "WITH (FILLFACTOR =", L"WITH (FILLFACTOR =", 18);
				Token::Change(value, 100 - int_value);

				Append(value, ")", L")", 1);
			}
			else
			// Oracle supports PCTFREE
			if(Target(SQL_ORACLE, SQL_DB2) == false)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 MINPCTUSED
		if(next->Compare("MINPCTUSED", L"MINPCTUSED", 10) == true)
		{
			Token *value = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS FREEPAGE num
		if(next->Compare("FREEPAGE", L"FREEPAGE", 8) == true)
		{
			Token *value = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS BUFFERPOOL name
		if(next->Compare("BUFFERPOOL", L"BUFFERPOOL", 10) == true)
		{
			Token *name = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// DB2 SPECIFICATION ONLY (index will be commented)
		if(next->Compare("SPECIFICATION", L"SPECIFICATION", 13) == true)
		{
			/*Token *only */ (void) GetNextWordToken("ONLY", L"ONLY", 4);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS GBPCACHE CHANGED | ALL | NONE  
		if(next->Compare("GBPCACHE", L"GBPCACHE", 8) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS CLOSE NO | YES  
		if(next->Compare("CLOSE", L"CLOSE", 5) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS COPY YES | NO  
		if(next->Compare("COPY", L"COPY", 4) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS PIECESIZE num [K | M | G]
		if(next->Compare("PIECESIZE", L"PIECESIZE", 9) == true)
		{
			Token *num = GetNextToken();

			if(num != NULL)
			{
				// Size can be optionally followed by specifier K, M or G
				Token *spec = Db2SizeSpecifier();

				if(_target != SQL_DB2)
				{
					Token::Remove(next, num);
					Token::Remove(spec);
				}

				exists = true;
				continue;
			}
		}
		else
		// DB2 for z/OS PADDED option
		if(next->Compare("PADDED", L"PADDED", 6) == true)
		{
			if(_target != SQL_DB2)
				Token::Remove(next);

			exists = true;
			continue;
		}
		
		// Not an index clause
		PushBack(next);

		break;
	}

	return exists;
}
Beispiel #13
0
// Generate output
void SqlParser::CreateOutputString(const char **output, int *out_size)
{
	if(output == NULL)
		return;

	Token *token = _tokens.GetFirst();

	int len = 0;

	int not_removed = 0;
	int removed = 0;

	// Calculate the output size in bytes and format output
	while(token != NULL)
	{
		bool r = false;
		bool n = false;

		// If token removed its target length is 0
		len += token->GetTargetLength();

		if(token->IsRemoved() == false)
		{
			r = token->Compare('\r', L'\r');

			if(r == false)
				n = token->Compare('\n', L'\n');
		}

		// Check if we need to remove newline (0D0A \r\n on Windows, 0D on Unix)
		if(r == true || n == true)
		{
			// String was not empty and all tokens removed
			if(not_removed == 0 && removed != 0)
			{
				Token::Remove(token);
				len--;

				// If current is \r and next is \n remove \n 
				if(r == true && token->next != NULL && token->next->Compare('\n', L'\n') == true)
				{
					// Its size will be reduced in the next iteration
					Token::Remove(token->next);
				}

				// Remove all spaces in this empty line
				Token *cur = token->prev;

				while(cur != NULL)
				{
					// Remove until new line
					if(cur->Compare('\n', L'\n') || cur->Compare('\r', L'\r'))
						break;

					if(cur->IsBlank() == true && cur->IsRemoved() == false)
					{
						Token::Remove(cur);
						len--;
					}

					cur = cur->prev;
				}
			}

			not_removed = 0;
			removed = 0;
		}
		// Calculate the number of removed and not removed tokens in line
		else
		{
			if(token->IsBlank() == false)
			{
				if(token->IsRemoved() == true)
					removed++;
				else
					not_removed++;
			}
		}

		token = _tokens.GetNext();
	}
	
	if(len == 0)
	{
		*output = NULL;

		if(out_size != NULL)
			*out_size = 0;

		return;
	}

	// Allocate buffer
	char *out = new char[len + 1]; *out = 0;

	token = _tokens.GetFirst();
	int cur_len = 0;

	while(token != NULL)
	{
		token->AppendTarget(out, &cur_len);

		token = _tokens.GetNext();
	}

	out[cur_len] = 0;

	*output = out; 

	if(out_size != NULL)
		*out_size = cur_len;
}
Beispiel #14
0
// Teradata CREATE TABLE options before column definition
bool SqlParser::ParseTeradataTableOptions()
{
	bool exists = false;

	// , goes after table name before even first option
	while(true)
	{
		Token *comma = GetNextCharToken(',', L',');

		if(comma == NULL)
			break;

		// Most options can start with NO keyword to disable option
		Token *no = GetNextWordToken("NO", L"NO", 2);

		Token *next = GetNextToken();

		if(next == NULL)
		{
			if(no != NULL)
				PushBack(no);

			break;
		}

		// [NO] FALLBACK to store a row copy
		if(next->Compare("FALLBACK", L"FALLBACK", 8) == true)
		{
			if(_target != SQL_TERADATA)
				Token::Remove(comma, next);

			exists = true;
			continue;
		}
		else
		// [NO] BEFORE JOURNAL to store before image
		if(next->Compare("BEFORE", L"BEFORE", 6) == true)
		{
			Token *journal = GetNextWordToken("JOURNAL", L"JOURNAL", 7);

			if(_target != SQL_TERADATA && journal != NULL)
				Token::Remove(comma, journal);

			exists = true;
			continue;
		}
		else
		// [NO] AFTER JOURNAL to store after image
		if(next->Compare("AFTER", L"AFTER", 5) == true)
		{
			Token *journal = GetNextWordToken("JOURNAL", L"JOURNAL", 7);

			if(_target != SQL_TERADATA && journal != NULL)
				Token::Remove(comma, journal);

			exists = true;
			continue;
		}

		if(no != NULL)
			PushBack(no);

		break;
	}

	return exists;
}
Beispiel #15
0
// DB2 CREATE DATABASE statement
bool SqlParser::Db2CreateDatabase(Token *create, Token * /*database*/, Token * /*name*/)
{
	bool exists = false;

	// CREATE DATABASE options
	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// BUFFERPOOL name
		if(next->Compare("BUFFERPOOL", L"BUFFERPOOL", 10) == true)
		{
			Token *name = GetNextToken();

			if(Target(SQL_DB2, SQL_ORACLE) == false)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// INDEXBP name
		if(next->Compare("INDEXBP", L"INDEXBP", 7) == true)
		{
			Token *name = GetNextToken();

			if(Target(SQL_DB2, SQL_ORACLE) == false)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// STOGROUP name
		if(next->Compare("STOGROUP", L"STOGROUP", 8) == true)
		{
			Token *name = GetNextToken();

			if(Target(SQL_DB2, SQL_ORACLE) == false)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// CCSID ASCII | EBCDIC | UNICODE
		if(next->Compare("CCSID", L"CCSID", 5) == true)
		{
			Token *code = GetNextToken();

			if(Target(SQL_DB2, SQL_ORACLE) == false)
				Token::Remove(next, code);

			exists = true;
			continue;
		}
	
		PushBack(next);
		break;
	}

	// Comment the entire statement for Oracle
	if(_target == SQL_ORACLE)
	{
		Token *end = GetLastToken(GetNextCharToken(';', L';'));
		Comment(create, end);
	}

	return exists;
}
Beispiel #16
0
// Get + or - as operator, not sign and number 
Token* SqlParser::GetNextPlusMinusAsOperatorToken(const char ch, const wchar_t wch)
{
	Token *token = GetNextToken();

	if(token == NULL)
		return NULL;

	// If + or - already returned as separate token then exit, for example when there is  "+ var"
	if(token->Compare(ch, wch) == true)
		return token;

	// If a number follows + or - they will be in single token as +1, but check for + or - first
	if(token->Compare(ch, wch, 0) == false)
	{
		PushBack(token);
		return NULL;
	}

	// Change the first token to hold operator +/-
	token->type = TOKEN_SYMBOL;
	token->chr = ch;
	token->wchr = 0;
	token->str = NULL;
	token->wstr = NULL;

	// Rewind input pointer
	_next_start -= token->len - 1;
	_remain_size += token->len - 1;

	token->len = 0;

	token->next_start = _next_start;
	token->remain_size = _remain_size;

	/*// Separate +/- operator and number constant tokens
	Token *token2 = new Token();

	*token2 = *token;

	token2->prev = NULL;
	token2->next = NULL;

	token2->t_str = NULL;
	token2->t_wstr = NULL;
	token2->t_len = 0;	

	// Second token hold number (decrease size by 1)
	token2->type = TOKEN_WORD;
	token2->chr = 0;
	token2->wchr = 0;
	token2->str = token2->str + 1;
	token2->wstr = 0;
	token2->len = token2->len - 1;

	_tokens.Append(token, token2);

	// Allow number to be selected as the next token
	PushBack(token2); */

	return token;
}
Beispiel #17
0
// Various SET options such as SET CURRENT SCHEMA
bool SqlParser::ParseDb2SetOptions(Token *set)
{
	bool exists = false;

	if(set == NULL)
		return false;

	// CURRENT is optional (SET SCHEMA is allowed)
	Token *current = GetNextWordToken("CURRENT", L"CURRENT", 7);

	Token *option = GetNextToken();

	if(option == NULL)
	{
		PushBack(current);
		return false;
	}

	// SET [CURRENT] PATH = list
	if(option->Compare("PATH", L"PATH", 4) == true)
	{
		// Optional =
		/*Token *equal */ (void) GetNextCharToken('=', L'=');

		// Comma-separated list of values
		while(true)
		{
			// Schema name
			/*Token *name */ (void) GetNextToken();

			Token *comma = GetNextCharToken(',', L',');

			if(comma == NULL)
				break;
		}

		// Remove the statement in Oracle
		if(_target == SQL_ORACLE)
			Token::Remove(set, Nvl(GetNextCharToken(';', L';'), GetLastToken()));

		exists = true;
	}
	else
	// SET [CURRENT] SCHEMA = name
	if(option->Compare("SCHEMA", L"SCHEMA", 6) == true)
	{
		// Optional =
		Token *equal = GetNextCharToken('=', L'=');

		// Schema name
		/*Token *name */ (void) GetNextToken();

		// ALTER SESSION SET CURRENT_SCHEMA = name in Oracle
		if(_target == SQL_ORACLE)
		{
			Prepend(set, "ALTER SESSION ", L"ALTER SESSION ", 14);
			
			Token::Remove(current);
			Token::Change(option, "CURRENT_SCHEMA", L"CURRENT_SCHEMA", 14);

			if(equal == NULL)
				AppendNoFormat(option, " =", L" =", 2);
		}

		exists = true;
	}
	// Not a SET option
	else
	{
		PushBack(option);
		PushBack(current);
	}

	return exists;
}
Beispiel #18
0
// SQL Server index options WITH (PAD_INDEX = OFF, ...)
bool SqlParser::ParseSqlServerIndexOptions(Token *token)
{
	if(token == NULL)
		return false;

	bool exists = false;

	// Start with WITH keyword
	if(token->Compare("WITH", L"WITH", 4) == false)
		return false;

	// ( can be omitted if FILLFACTOR is only specified
	Token *open = GetNext('(', L'(');

	while(true)
	{
		bool remove = false;

		Token *option = GetNextToken();

		if(option == NULL)
			break;

		// = between option name and value
		/*Token *equal */ (void) GetNext('=', L'=');

		Token *value = NULL;

		// ALLOW_PAGE_LOCKS = ON | OFF
		if(option->Compare("ALLOW_PAGE_LOCKS", L"ALLOW_PAGE_LOCKS", 16) == true)
		{
			value = GetNextToken();

			if(_target != SQL_SQL_SERVER)
				remove = true;

			exists = true;
		}
		else
		// ALLOW_ROW_LOCKS = ON | OFF
		if(option->Compare("ALLOW_ROW_LOCKS", L"ALLOW_ROW_LOCKS", 15) == true)
		{
			value = GetNextToken();

			if(_target != SQL_SQL_SERVER)
				remove = true;

			exists = true;
		}
		else
		// FILLFACTOR = num
		if(option->Compare("FILLFACTOR", L"FILLFACTOR", 10) == true)
		{
			value = GetNextToken();

			if(_target != SQL_SQL_SERVER)
				remove = true;

			exists = true;
		}
		else
		// IGNORE_DUP_KEY = ON | OFF
		if(option->Compare("IGNORE_DUP_KEY", L"IGNORE_DUP_KEY", 14) == true)
		{
			value = GetNextToken();

			if(_target != SQL_SQL_SERVER)
				remove = true;

			exists = true;
		}
		else
		// PAD_INDEX = ON | OFF
		if(option->Compare("PAD_INDEX", L"PAD_INDEX", 9) == true)
		{
			value = GetNextToken();

			if(_target != SQL_SQL_SERVER)
				remove = true;

			exists = true;
		}
		else
		// STATISTICS_NORECOMPUTE = ON | OFF
		if(option->Compare("STATISTICS_NORECOMPUTE", L"STATISTICS_NORECOMPUTE", 22) == true)
		{
			value = GetNextToken();

			if(_target != SQL_SQL_SERVER)
				remove = true;

			exists = true;
		}
		else
		{
			PushBack(option);
			break;
		}

		Token *comma = GetNext(',', L',');

		// Remove the option
		if(remove == true)
		{
			Token::Remove(option, value);
			Token::Remove(comma);
		}

		if(comma == NULL)
			break;
	}

	if(exists == false)
	{
		// PostgreSQL also has WITH ( ... option, so return open token
		PushBack(open);

		return false;
	}

	Token *close = GetNext(open, ')', L')');

	// Remove WITH ()
	if(_target != SQL_SQL_SERVER)
	{
		Token::Remove(token);
		Token::Remove(open);
		Token::Remove(close);
	}

	// Storage clause can follow 
	ParseSqlServerStorageClause();

	return exists;
}
Beispiel #19
0
// Parse Informix CREATE TABLE storage clause
bool SqlParser::ParseInformixStorageClause()
{
	bool exists = false;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// EXTENT SIZE num
		if(next->Compare("EXTENT", L"EXTENT", 6) == true)
		{
			Token *size = GetNextWordToken("SIZE", L"SIZE", 4);
			Token *num = GetNextToken(size);

			if(_target != SQL_INFORMIX && num != NULL)
				Token::Remove(next, num);

			exists = true;
			continue;
		}
		else
		// FRAGMENT BY partitioning clause
		if(next->Compare("FRAGMENT", L"FRAGMENT", 8) == true)
		{
			ParseInformixFragmentBy(next);

			exists = true;
			continue;
		}
		else
		// IN dbspace
		if(next->Compare("IN", L"IN", 2) == true)
		{
			// Get database space name
			Token *name = GetNextToken();

			// TABLESPACE name in Oracle
			if(_target == SQL_ORACLE)
				Token::Change(next, "TABLESPACE", L"TABLESPACE", 10);
			else
			// DB2 also uses IN keyword to specify a tablespace
			if(Target(SQL_DB2, SQL_INFORMIX) == false)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// LOCK MODE PAGE | ROW | TABLE
		if(next->Compare("LOCK", L"LOCK", 4) == true)
		{
			Token *mode = GetNextWordToken("MODE", L"MODE", 4);
			Token *type = GetNextToken(mode);

			if(_target != SQL_INFORMIX && type != NULL)
				Token::Remove(next, type);

			exists = true;
			continue;
		}
		else
		// NEXT SIZE num
		if(next->Compare("NEXT", L"NEXT", 4) == true)
		{
			Token *size = GetNextWordToken("SIZE", L"SIZE", 4);
			Token *num = GetNextToken(size);

			if(_target != SQL_INFORMIX && num != NULL)
				Token::Remove(next, num);

			exists = true;
			continue;
		}

		// Not a storage clause
		PushBack(next);
		break;
	}

	return exists;
}
Beispiel #20
0
// Parse Oracle CREATE TABLE, CREATE INDEX, PARTITION definition storage clause
bool SqlParser::ParseOracleStorageClause(int stmt_scope)
{
	bool exists = false;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// SEGMENT CREATION IMMEDIATE | DEFERRED
		if(next->Compare("SEGMENT", L"SEGMENT", 7) == true)
		{
			Token *creation = GetNextWordToken("CREATION", L"CREATION", 8);
			Token *value = GetNextToken();

			if(_target != SQL_ORACLE && creation != NULL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// PCTFREE num
		if(next->Compare("PCTFREE", L"PCTFREE", 7) == true)
		{
			Token *value = GetNextNumberToken();

			if(_target != SQL_ORACLE && value != NULL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// PCTUSED num
		if(next->Compare("PCTUSED", L"PCTUSED", 7) == true)
		{
			Token *value = GetNextNumberToken();

			if(_target != SQL_ORACLE && value != NULL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// INITRANS num
		if(next->Compare("INITRANS", L"INITRANS", 8) == true)
		{
			Token *value = GetNextNumberToken();

			if(_target != SQL_ORACLE && value != NULL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// MAXTRANS num
		if(next->Compare("MAXTRANS", L"MAXTRANS", 8) == true)
		{
			Token *value = GetNextNumberToken();

			if(_target != SQL_ORACLE && value != NULL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// COMPRESS [BASIC] or COMPRESS num (for index-orginized tables and indexes)
		if(next->Compare("COMPRESS", L"COMPRESS", 8) == true)
		{
			// Optional BASIC keyword
			Token *basic = GetNextWordToken("BASIC", L"BASIC", 5);
			Token *num = NULL;

			// Check for a number
			if(basic == NULL)
				num = GetNextNumberToken();

			if(_target != SQL_ORACLE)
			{
				Token::Remove(next);
				Token::Remove(basic);
				Token::Remove(num);
			}

			exists = true;
			continue;
		}
		else
		// NOCOMPRESS 
		if(next->Compare("NOCOMPRESS", L"NOCOMPRESS", 10) == true)
		{
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// NOCACHE 
		if(next->Compare("NOCACHE", L"NOCACHE", 7) == true)
		{
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// LOGGING 
		if(next->Compare("LOGGING", L"LOGGING", 7) == true)
		{
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// NOLOGGING 
		if(next->Compare("NOLOGGING", L"NOLOGGING", 9) == true)
		{
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// NOPARALLEL 
		if(next->Compare("NOPARALLEL", L"NOPARALLEL", 10) == true)
		{
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// PARALLEL num
		if(next->Compare("PARALLEL", L"PARALLEL", 8) == true)
		{
			Token *value = GetNextNumberToken();

			if(_target != SQL_ORACLE && value != NULL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// NOMONITORING 
		if(next->Compare("NOMONITORING", L"NOMONITORING", 12) == true)
		{
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// TABLESPACE name 
		if(next->Compare("TABLESPACE", L"TABLESPACE", 10) == true)
		{
			Token *name = GetNextIdentToken();

			// ON name
			if(_target == SQL_SQL_SERVER)
				Token::Change(next, "ON", L"ON", 2);
			else
			// IN name
			if(_target == SQL_DB2)
				Token::Change(next, "IN", L"IN", 2);
			else
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// STORAGE () clause 
		if(next->Compare("STORAGE", L"STORAGE", 7) == true)
		{
			exists = ParseOracleStorageClause(next);
			continue;
		}
		else
		// LOB (column) STORE AS (params)
		if(next->Compare("LOB", L"LOB", 3) == true)
		{
			if(ParseOracleLobStorageClause(next) == true)
			{
				exists = true;
				continue;
			}
		}
		else
		// Oracle partitioning clauses
		if(ParseOraclePartitions(next, stmt_scope) == true)
		{
			exists = true;
			continue;
		}
		else
		// COMPUTE STATISTICS 
		if(next->Compare("COMPUTE", L"COMPUTE", 7) == true)
		{
			Token *statistics = GetNextWordToken("STATISTICS", L"STATISTICS", 10);

			// Remove if not Oracle
			if(_target != SQL_ORACLE)
				Token::Remove(next, statistics);

			exists = true;
			continue;
		}
		else
		// ENABLE ROW MOVEMENT 
		if(next->Compare("ENABLE", L"ENABLE", 6) == true)
		{
			Token *row = GetNextWordToken("ROW", L"ROW", 3);

			if(row != NULL)
			{
				Token *movement = GetNextWordToken("MOVEMENT", L"MOVEMENT", 8);
			
				// Remove if not Oracle
				if(_target != SQL_ORACLE)
					Token::Remove(next, movement);

				exists = true;
				continue;
			}
		}
		else
		// REVERSE index or primary key storage attribute 
		if(next->Compare("REVERSE", L"REVERSE", 7) == true)
		{
			// Remove if not Oracle
			if(_target != SQL_ORACLE)
				Token::Remove(next);

			exists = true;
			continue;
		}
		
		// Not an Oracle storage clause
		PushBack(next);
		break;
	}

	return exists;
}
Beispiel #21
0
// Temporary table options
bool SqlParser::ParseTempTableOptions(Token *table_name, Token **start_out, Token **end_out, bool *no_data)
{
	bool exists = false;

	Token *start = NULL;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		if(start == NULL)
			start = next;

		// ON COMMIT PRESERVE | DELETE ROWS in Oracle, DB2; ON ROLLBACK PRESERVE | DELETE ROWS in DB2   
		if(next->Compare("ON", L"ON", 2) == true)
		{
			Token *commit = GetNextWordToken("COMMIT", L"COMMIT", 6);
			Token *rollback = NULL;

			if(commit == NULL)
				rollback = GetNextWordToken("ROLLBACK", L"ROLLBACK", 8);

			if(commit == NULL && rollback == NULL)
				break;

			Token *delete_ = GetNextWordToken("DELETE", L"DELETE", 6);
			Token *preserve = NULL;

			if(delete_ == NULL)
				preserve = GetNextWordToken("PRESERVE", L"PRESERVE", 8);

			Token *rows = GetNextWordToken("ROWS", L"ROWS", 4);

			if(_target == SQL_SQL_SERVER)
				Token::Remove(next, rows);
			else
			// Oracle does not support ON ROLLBACK, but DELETE ROWS in default on rollback
			if(_target == SQL_ORACLE && rollback != NULL) 
			{
				if(delete_ != NULL)
					Token::Remove(next, rows);
				else
					Comment(next, rows);
			}
			
			exists = true;
			continue;
		}
		else
		// NOT LOGGED in DB2   
		if(next->Compare("NOT", L"NOT", 3) == true)
		{
			Token *logged = GetNextWordToken("LOGGED", L"LOGGED", 6);

			if(logged != NULL)
			{
				if(_target == SQL_ORACLE) 
					Token::Remove(next, logged);

				exists = true;
				continue;
			}
		}
		else
		// WITH REPLACE, WITH NO DATA in DB2   
		if(next->Compare("WITH", L"WITH", 4) == true)
		{
			Token *replace = GetNextWordToken("REPLACE", L"REPLACE", 7);
			Token *no = NULL;

			if(replace == NULL)
				no = GetNextWordToken("NO", L"NO", 2);

			// WITH REPLACE in DB2
			if(replace != NULL)
			{
				if(Target(SQL_DB2) == false) 
					Token::Remove(next, replace);

				_spl_declared_tables_with_replace.Add(table_name);

				exists = true;
				continue;
			}
			else
			// WITH NO DATA in DB2
			if(no != NULL)
			{
				Token *data = GetNextWordToken("DATA", L"DATA", 4);

				if(data != NULL)
				{
					if(_target == SQL_ORACLE) 
						Token::Remove(next, data);

					if(no_data != NULL)
						*no_data = true;

					exists = true;
					continue;
				}
			}
		}
		else
		// DEFINITION ONLY in DB2   
		if(next->Compare("DEFINITION", L"DEFINITION", 10) == true)
		{
			Token *only = GetNextWordToken("ONLY", L"ONLY", 4);

			if(only != NULL)
			{
				if(_target == SQL_ORACLE) 
					Token::Remove(next, only);

				if(no_data != NULL)
					*no_data = true;

				exists = true;
				continue;
			}
		}
		else
		// IN tablespace in DB2   
		if(next->Compare("IN", L"IN", 2) == true)
		{
			Token *tablespace_name = GetNextToken();

			if(tablespace_name != NULL)
			{
				if(_target == SQL_ORACLE) 
					Token::Remove(next, tablespace_name);

				exists = true;
				continue;
			}
		}
				
		// Not a temporary table clause
		PushBack(next);
		break;
	}

	if(exists == true)
	{
		if(start_out != NULL)
			*start_out = start;

		if(end_out != NULL)
			*end_out = GetLastToken();
	}

	return exists;
}
Beispiel #22
0
// Parse MySQL CREATE TABLE storage clause
bool SqlParser::ParseMysqlStorageClause(Token *table_name, Token **id_start, Token **comment_out)
{
	bool exists = false;

	// Auto_increment start value
	Token *auto_start = NULL;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// ENGINE = type
		if(next->Compare("ENGINE", L"ENGINE", 6) == true)
		{
			// Equal sign = is optional in the clause
			Token *equal = GetNextCharToken('=', L'=');
			Token *type = GetNextToken();

			if(_target != SQL_MYSQL)
			{
				Token::Remove(next);
				Token::Remove(equal);
				Token::Remove(type);
			}

			exists = true;
			continue;
		}
		else
		// AUTO_INCREMENT = start table option
		if(next->Compare("AUTO_INCREMENT", L"AUTO_INCREMENT", 14) == true)
		{
			// Equal sign = is optional in the clause
			Token *equal = GetNextCharToken('=', L'=');
			auto_start = GetNextNumberToken();

			if(_target != SQL_MYSQL)
			{
				Token::Remove(next);
				Token::Remove(equal);
				Token::Remove(auto_start);
			}

			exists = true;
			continue;
		}
		else
		// DEFAULT CHARSET
		if(next->Compare("DEFAULT", L"DEFAULT", 7) == true)
		{
			Token *option = GetNextToken();

			if(option == NULL)
				break;

			// CHARSET
			if(option->Compare("CHARSET", L"CHARSET", 7) == true)
			{
				Token *equal = GetNextCharToken('=', L'=');
				Token *value = GetNextIdentToken();

				if(_target != SQL_MYSQL)
					Token::Remove(next, value);
			}
			else
			// CHARACTER SET
			if(option->Compare("CHARACTER", L"CHARACTER", 9) == true)
			{
				Token *set = GetNextWordToken("SET", L"SET", 3);
				Token *equal = GetNextCharToken('=', L'=');
				Token *value = GetNextIdentToken();

				if(_target != SQL_MYSQL)
					Token::Remove(next, value);
			}

			exists = true;
			continue;
		}
		else
		// COLLATE = value
		if(next->Compare("COLLATE", L"COLLATE", 7) == true)
		{
			Token *equal = GetNextCharToken('=', L'=');
			Token *value = GetNextIdentToken();

			if(_target != SQL_MYSQL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// COMMENT = 'table comment'
		if(next->Compare("COMMENT", L"COMMENT", 7) == true)
		{
			// Equal sign = is optional in the clause
			Token *equal = GetNextCharToken('=', L'=');
			Token *text = GetNextToken();

			if(comment_out != NULL)
				*comment_out = text;

			// Remove from CREATE TABLE
			if(_target != SQL_MYSQL)
				Token::Remove(next, text);

			exists = true;
			continue;
		}
		else
		// PACK_KEYS = 0 | 1 | DEFAULT
		if(next->Compare("PACK_KEYS", L"PACK_KEYS", 9) == true)
		{
			// Optional = 
			Token *equal = GetNextCharToken('=', L'=');
			Token *value = GetNextToken();

			if(_target != SQL_MYSQL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// ROW_FORMAT = type | DEFAULT
		if(next->Compare("ROW_FORMAT", L"ROW_FORMAT", 10) == true)
		{
			// Optional = 
			Token *equal = GetNextCharToken('=', L'=');
			Token *value = GetNextToken();

			if(_target != SQL_MYSQL)
				Token::Remove(next, value);

			exists = true;
			continue;
		}

		// Not a MySQL stoage clause
		PushBack(next);

		break;
	}

	if(id_start != NULL)
		*id_start = auto_start;

	// Restart sequence for PostgreSQL and Greenplum
	if(auto_start != NULL && (_target == SQL_POSTGRESQL || _target == SQL_GREENPLUM))
	{
		// Try to get ;
		Token *semi = GetNextCharToken(';', L';');

		Token *last = (semi != NULL) ? semi : GetLastToken();

		// Append ALTER SEQUENCE command
		Append(last, "\n\nALTER SEQUENCE ", L"\n\nALTER SEQUENCE ", 17);

		// Add sequence name
		Token *seq_name = AppendIdentifier(table_name, "_seq", L"_seq", 4);
		Append(last, seq_name);

		Append(last, " RESTART WITH ", L" RESTART WITH ", 14);
		AppendCopy(last, auto_start);
		Append(last, ";", L";", 1);
	}

	return exists;
}
Beispiel #23
0
// DB2 identity options in GENERATED ALWAYS or BY DEFAULT AS IDENTITY
bool SqlParser::ParseDb2GeneratedClause(Token *create, Token *table_name, Token *column, Token *generated,
									Token **id_col, Token **id_start, Token **id_inc, bool *id_default)
{
	if(generated == NULL)
		return false;

	Token *always = GetNextWordToken("ALWAYS", L"ALWAYS", 6);
	Token *by = NULL;
	Token *default_ = NULL;

	if(always == NULL)
	{
		by = GetNextWordToken("BY", L"BY", 2);
		default_ = GetNextWordToken("DEFAULT", L"DEFAULT", 7);

		if(id_default != NULL)
			*id_default = true;
	}
	else
	{
		if(id_default != NULL)
			*id_default = false;
	}
	
	Token *as = GetNextWordToken("AS", L"AS", 2);
	Token *identity = GetNextWordToken("IDENTITY", L"IDENTITY", 8);

	// Identity parameters are optional
	Token *open = GetNextCharToken('(', L'(');
	Token *close = NULL;

	Token *start_with = NULL;
	Token *increment_by = NULL;

	while(true)
	{
		bool exists = false;

		if(open == NULL)
			break;

		Token *option = GetNextToken();

		if(option == NULL)
			break;

		// START WITH
		if(option->Compare("START", L"START", 5) == true)
		{
			/*Token *with */ (void) GetNextWordToken("WITH", L"WITH", 4);
			start_with = GetNextNumberToken();

			exists = true;
			continue;
		}
		else
		// INCREMENT BY
		if(option->Compare("INCREMENT", L"INCREMENT", 9) == true)
		{
			/*Token *by */ (void) GetNextWordToken("BY", L"BY", 2);
			increment_by = GetNextNumberToken();

			exists = true;
			continue;
		}
		else
		// MINVALUE
		if(option->Compare("MINVALUE", L"MINVALUE", 8) == true)
		{
			/*Token *value */ (void) GetNextNumberToken();

			exists = true;
			continue;
		}
		else
		// MAXVALUE
		if(option->Compare("MAXVALUE", L"MAXVALUE", 8) == true)
		{
			/*Token *value */ (void) GetNextNumberToken();

			exists = true;
			continue;
		}
		else
		// NO CYCLE and NO ORDER
		if(option->Compare("NO", L"NO", 2) == true)
		{
			/*Token *attr */ (void) GetNextToken();

			exists = true;
			continue;
		}
		else
		// CACHE
		if(option->Compare("CACHE", L"CACHE", 5) == true)
		{
			/*Token *value */ (void) GetNextNumberToken();

			exists = true;
			continue;
		}
		else
		// CYCLE
		if(option->Compare("CYCLE", L"CYCLE", 5) == true)
		{
			exists = true;
			continue;
		}
		else
		// Looks like comma is optional
		if(option->Compare(',', L',') == true)
		{
			exists = true;
			continue;
		}

		PushBack(option);
		break;
	}

	if(open != NULL)
		close = GetNextCharToken(')', L')');
	
	// IDENTITY(start, inc) in SQL Server
	if(_target == SQL_SQL_SERVER)
	{
		Token::Change(generated, "IDENTITY(", L"IDENTITY(", 9);
		AppendCopy(generated, start_with);

		if(increment_by != NULL)
		{
			Append(generated, ", ", L", ", 2);
			AppendCopy(generated, increment_by);
		}

		Append(generated, ")", L")", 1);

		if(always != NULL)
			Token::Remove(always, close);
		else
			Token::Remove(by, close);
	}
	else
	// Use a sequence and DEFAULT nextval for PostgreSQL and Greenplum
	if(_target == SQL_POSTGRESQL || _target == SQL_GREENPLUM)
	{
		TokenStr seq_name(table_name);

		AppendIdentifier(seq_name, "_seq", L"_seq", 4);
		
		// Generate CREATE SEQUENCE before CREATE TABLE
		Prepend(create, "CREATE SEQUENCE ", L"CREATE SEQUENCE ", 16);
		PrependNoFormat(create, &seq_name);

		if(start_with != NULL)
		{
			Prepend(create, " START WITH ", L" START WITH ", 12);
			PrependCopy(create, start_with);
		}

		if(increment_by != NULL)
		{
			Prepend(create, " INCREMENT BY ", L" INCREMENT BY ", 14);
			PrependCopy(create, increment_by);
		}

		Prepend(create, ";\n\n", L";\n\n", 3);

		// Generate DEFAULT nextval('tablename_seq') clause
		Token::Change(generated, "DEFAULT ", L"DEFAULT ", 8);
		Append(generated, "nextval ('", L"nextval ('", 10);

		AppendNoFormat(generated, &seq_name);
		Append(generated, "')", L"')", 2);

		if(always != NULL)
			Token::Remove(always, close);
		else
			Token::Remove(by, close);
	}
	else
	// Remove for other databases
	if(_target != SQL_DB2)
	{
		Token::Remove(generated);

		Token::Remove(always);
		Token::Remove(by, default_);
		Token::Remove(as, identity);
		
		Token::Remove(open, close);
	}

	if(id_col != NULL)
		*id_col = column; 

	if(id_start != NULL)
		*id_start = start_with;
	
	if(id_inc != NULL)
		*id_inc = increment_by;

	return true;
}
Beispiel #24
0
// Parse DB2 CREATE TABLE storage clause
bool SqlParser::ParseDb2StorageClause()
{
	bool exists = false;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// IN tablespace
		if(next->Compare("IN", L"IN", 2) == true)
		{
			// Get tablespace name (can include database name: dbname.tbsname)
			Token *name = GetNextIdentToken();

			// TABLESPACE name in Oracle
			if(_target == SQL_ORACLE)
			{
				Token::Change(next, "TABLESPACE", L"TABLESPACE", 10);

				// Name can contain database name, remove it
				ConvertIdentRemoveLeadingPart(name);
			}
			else
			if(_target != SQL_DB2)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// INDEX IN tablespace
		if(next->Compare("INDEX", L"INDEX", 5) == true)
		{
			Token *in = GetNextWordToken("IN", L"IN", 2);
			Token *name = GetNextIdentToken();

			if(_target != SQL_DB2)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// COMPRESS YES | NO clause
		if(next->Compare("COMPRESS", L"COMPRESS", 8) == true)
		{
			Token *yesno = GetNextToken();
			
			if(_target != SQL_DB2)
				Token::Remove(next, yesno);

			exists = true;
			continue;
		}
		else
		// CCSID ASCII | UNICODE | EBCDIC
		if(next->Compare("CCSID", L"CCSID", 5) == true)
		{
			Token *encoding = GetNextToken();
			
			if(_target != SQL_DB2)
				Token::Remove(next, encoding);

			exists = true;
			continue;
		}
		else
		// DATA CAPTURE CHANGES | NONE
		if(next->Compare("DATA", L"DATA", 4) == true)
		{
			Token *capture = GetNextWordToken("CAPTURE", L"CAPTURE", 7);
			Token *option = NULL;
			
			if(capture != NULL)
			{
				option = GetNextToken();
			
				if(_target != SQL_DB2)
					Token::Remove(next, option);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS AUDIT CHANGES | NONE | ALL
		if(next->Compare("AUDIT", L"AUDIT", 5) == true)
		{
			Token *option = GetNextToken();
			
			if(_target != SQL_DB2)
				Token::Remove(next, option);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS WITH RESTRICT ON DROP  
		if(next->Compare("WITH", L"WITH", 4) == true)
		{
			Token *restrict = GetNextWordToken("RESTRICT", L"RESTRICT", 8);
			Token *on = NULL;
			Token *drop = NULL;

			if(restrict != NULL)
			{
				on = GetNextWordToken("ON", L"ON", 2);

				if(on != NULL)
					drop = GetNextWordToken("DROP", L"DROP", 4);

				if(_target != SQL_DB2)
					Token::Remove(next, drop);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS NOT VOLATILE  
		if(next->Compare("NOT", L"NOT", 3) == true)
		{
			Token *volatile_ = GetNextWordToken("VOLATILE", L"VOLATILE", 8);

			if(volatile_ != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, volatile_);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS VOLATILE  
		if(next->Compare("VOLATILE", L"VOLATILE", 8) == true)
		{
			if(_target != SQL_DB2)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS APPEND NO | YES  
		if(next->Compare("APPEND", L"APPEND", 6) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// PARTITION BY SIZE EVERY n G 
		if(next->Compare("PARTITION", L"PARTITION", 9) == true)
		{
			Token *by = GetNextWordToken("BY", L"BY", 2);
			Token *size = GetNextWordToken(by, "SIZE", L"SIZE", 4);

			// Partition by size
			if(size != NULL)
			{
				// Optional EVERY n G
				Token *every = GetNextWordToken("EVERY", L"EVERY", 5);
				Token *num = GetNextToken(every);
				Token *g = GetNextWordToken("G", L"G", 1);

				if(_target != SQL_DB2)
				{
					Token::Remove(next, size);
					Token::Remove(every, num);
					Token::Remove(g);
				}

				exists = true;
				continue;
			}
			else
			if(ParseDb2PartitioningClause(next, by) == true)
			{
				exists = true;
				continue;
			}
		}

		// Not a DB2 storage clause
		PushBack(next);

		break;
	}

	return exists;
}
Beispiel #25
0
// DB2 CREATE TABLESPACE
bool SqlParser::ParseDb2CreateTablespace(Token *create, Token *tablespace)
{
	if(create == NULL || tablespace == NULL)
		return false;

	// Tablespace name
	Token *name = GetNextToken();

	if(name == NULL)
		return false;

	bool exists = false;

	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// IN database
		if(next->Compare("IN", L"IN", 2) == true)
		{
			Token *database = GetNextToken();

			if(database != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, database);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS USING STOGROUP
		if(next->Compare("USING", L"USING", 5) == true)
		{
			Token *stogroup = GetNextWordToken("STOGROUP", L"STOGROUP", 8);

			if(stogroup != NULL)
				ParseDb2StogroupClause(name, next, stogroup, SQL_SCOPE_TABLESPACE);

			exists = true;
			continue;
		}
		else
		// DB2 COMPRESS NO | YES option
		if(next->Compare("COMPRESS", L"COMPRESS", 8) == true)
		{
			Token *value = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 PCTFREE
		if(next->Compare("PCTFREE", L"PCTFREE", 7) == true)
		{
			Token *value = GetNextToken();

			// Oracle does not support PCTFREE in CREATE TABLESPACE
			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS FREEPAGE num
		if(next->Compare("FREEPAGE", L"FREEPAGE", 8) == true)
		{
			Token *value = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS BUFFERPOOL name
		if(next->Compare("BUFFERPOOL", L"BUFFERPOOL", 10) == true)
		{
			Token *name = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, name);

			exists = true;
			continue;
		}
		else
		// DB2 z/OS GBPCACHE CHANGED | ALL | SYSTME | NONE  
		if(next->Compare("GBPCACHE", L"GBPCACHE", 8) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS CLOSE NO | YES  
		if(next->Compare("CLOSE", L"CLOSE", 5) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS COPY YES | NO  
		if(next->Compare("COPY", L"COPY", 4) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS PIECESIZE num [K | M | G]
		if(next->Compare("PIECESIZE", L"PIECESIZE", 9) == true)
		{
			Token *num = GetNextToken();

			if(num != NULL)
			{
				// Size can be optionally followed by specifier K, M or G
				Token *spec = Db2SizeSpecifier();

				if(_target != SQL_DB2)
				{
					Token::Remove(next, num);
					Token::Remove(spec);
				}

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS LOGGED option
		if(next->Compare("LOGGED", L"LOGGED", 6) == true)
		{
			if(_target == SQL_ORACLE)
				Token::Change(next, "LOGGING", L"LOGGING", 7);
			else
			if(_target != SQL_DB2)
				Token::Remove(next);

			exists = true;
			continue;
		}
		else
		// DB2 for z/OS NOT LOGGED
		if(next->Compare("NOT", L"NOT", 3) == true)
		{
			Token *logged = GetNextWordToken("LOGGED", L"LOGGED", 6);

			if(logged != NULL)
			{
				if(_target == SQL_ORACLE)
				{
					Token::Change(next, "NOLOGGING", L"NOLOGGING", 9);
					Token::Remove(logged);
				}
				else
				if(_target != SQL_DB2)
					Token::Remove(next, logged);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS TRACKMOD NO | YES  
		if(next->Compare("TRACKMOD", L"TRACKMOD", 8) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS SEGSIZE num  
		if(next->Compare("SEGSIZE", L"SEGSIZE", 7) == true)
		{
			Token *num = GetNextToken();

			if(num != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, num);

				exists = true;
				continue;
			}
		}
		else
		// DB2 z/OS LOCKSIZE ANY | TABLESPACE | TABLE | PAGE | ROW | LOB
		if(next->Compare("LOCKSIZE", L"LOCKSIZE", 8) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// DB2 for z/OS LOCKMAX num | SYSTEM
		if(next->Compare("LOCKMAX", L"LOCKMAX", 7) == true)
		{
			Token *value = GetNextToken();

			if(value != NULL)
			{
				if(_target != SQL_DB2)
					Token::Remove(next, value);

				exists = true;
				continue;
			}
		}
		else
		// CCSID ASCII | UNICODE | EBCDIC
		if(next->Compare("CCSID", L"CCSID", 5) == true)
		{
			Token *encoding = GetNextToken();
			
			if(_target != SQL_DB2)
				Token::Remove(next, encoding);

			exists = true;
			continue;
		}
		else
		// DB2 for z/OS MAXROWS num 
		if(next->Compare("MAXROWS", L"MAXROWS", 7) == true)
		{
			Token *num = GetNextToken();
			
			if(_target != SQL_DB2)
				Token::Remove(next, num);

			exists = true;
			continue;
		}

		PushBack(next);
		break;
	}

	return exists;
}
Beispiel #26
0
// DB2 z/OS USING STOGROUP clause
bool SqlParser::ParseDb2StogroupClause(Token *objname, Token *using_, Token *stogroup, int scope)
{
	if(using_ == NULL || stogroup == NULL)
		return false;

	// STOGROUP name
	Token *name = GetNextToken();

	if(name == NULL)
		return false;

	bool exists = false;

	// STOGROUP options
	while(true)
	{
		Token *next = GetNextToken();

		if(next == NULL)
			break;

		// PRIQTY num
		if(next->Compare("PRIQTY", L"PRIQTY", 6) == true)
		{
			Token *num = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, num);

			exists = true;
			continue;
		}
		else
		// SECQTY num
		if(next->Compare("SECQTY", L"SECQTY", 6) == true)
		{
			Token *num = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, num);

			exists = true;
			continue;
		}
		else
		// ERASE NO | YES
		if(next->Compare("ERASE", L"ERASE", 5) == true)
		{
			Token *value = GetNextToken();

			if(_target != SQL_DB2)
				Token::Remove(next, value);

			exists = true;
			continue;
		}
	
		PushBack(next);
		break;
	}

	// Set DATAFILE clause in CREATE TABLESPACE for Oracle
	if(_target == SQL_ORACLE && scope == SQL_SCOPE_TABLESPACE)
	{
		Token::Change(using_, "DATAFILE '", L"DATAFILE '", 10);

		// Use tablespace name as multiple tablespaces can be created in a single storage group
		AppendCopy(using_, objname);
		Append(using_, ".dbf'", L".dbf'", 5);

		Token::Remove(stogroup);
		Token::Remove(name);
	}
	else
	if(_target != SQL_DB2)
		Token::Remove(using_, name);

	return exists;
}
Beispiel #27
0
// SQL Server SET options, SET ANSI_NULLS ON i.e
bool SqlParser::ParseSqlServerSetOptions(Token *set)
{
	if(set == NULL)
		return false;

	bool exists = false;

	bool comment = false;
	bool remove = false;

	Token *option = GetNextToken();

	if(option == NULL)
		return false;

	// SET ANSI_NULLS ON | OFF
	if(option->Compare("ANSI_NULLS", L"ANSI_NULLS", 10) == true)
	{
		/*Token *value */ (void) GetNextToken();

		if(_target != SQL_SQL_SERVER)
			comment = true;

		exists = true;
	}
	else
	// SET ANSI_PADDING ON | OFF
	if(option->Compare("ANSI_PADDING", L"ANSI_PADDING", 12) == true)
	{
		/*Token *value */ (void) GetNextToken();

		if(_target != SQL_SQL_SERVER)
			comment = true;

		exists = true;
	}
	else
	// SET NOCOUNT ON | OFF
	if(option->Compare("NOCOUNT", L"NOCOUNT", 7) == true)
	{
		/*Token *value */ (void) GetNextToken();

		if(_target != SQL_SQL_SERVER)
			remove = true;

		exists = true;
	}
	else
	// SET QUOTED_IDENTIFIER ON | OFF
	if(option->Compare("QUOTED_IDENTIFIER", L"QUOTED_IDENTIFIER", 17) == true)
	{
		/*Token *value */ (void) GetNextToken();

		if(_target != SQL_SQL_SERVER)
			comment = true;

		exists = true;
	}
	// Not a SET option
	else
		PushBack(option);

	if(exists == true)
	{
		Token *last = Nvl(GetNextCharToken(';', L';'), GetLastToken());

		if(comment == true)
			Comment(set, last);
		else
		if(remove == true)
			Token::Remove(set, last);

		// Remove following GO if any
		SqlServerGoDelimiter(true);
	}

	return exists;
}