sqlparser/language.cpp
// Parse PRIMARY KEY, UNIQUE constraint clause, and INDEX/KEY in MySQL 
Parse PRIMARY KEY, UNIQUE constraint clause, and INDEX/KEY in MySQL
Parse PRIMARY KEY UNIQUE constraint clause and INDEX / KEY in MySQL
bool SqlParser::ParseKeyConstraint(Token * , Token *table_name, Token *cns, ListW &pkcols, 
									bool inline_cns, ListWM *inline_indexes)
{
	if(cns == NULL)
		return false;
	bool primary = false;
	bool unique = false; 
	bool unique_index = false;
	bool index = false;
	Token *index_name = NULL;
	if(cns->Compare("PRIMARY", L"PRIMARY", 7) == true)
	{
		 (void) GetNextWordToken("KEY", L"KEY", 3);
		primary = true;
        if(_stmt_scope == SQL_STMT_ALTER_TABLE)
            ALTER_TAB_STMS_STATS("Add PRIMARY KEY")
	}
	else
	if(cns->Compare("UNIQUE", L"UNIQUE", 6) == true)
	{
		unique = true;
		Token *index = GetNextWordToken("INDEX", L"INDEX", 5);
		if(index == NULL)
			index = GetNextWordToken("KEY", L"KEY", 3);
		if(index != NULL)
		{
			unique_index = true;
			index_name = GetNextIdentToken();
			if(_target != SQL_MYSQL)
			{
				if(index_name != NULL)
				{
					Prepend(cns, "CONSTRAINT ", L"CONSTRAINT ", 11);
					PrependCopy(cns, index_name);
					PrependNoFormat(cns, " ", L" ", 1);
					Token::Remove(index_name);
				}
				Token::Remove(index);
			}
		}
        if(_stmt_scope == SQL_STMT_ALTER_TABLE)
            ALTER_TAB_STMS_STATS("Add UNIQUE constraint")
	}
	else
	if(cns->Compare("INDEX", L"INDEX", 5) == true || cns->Compare("KEY", L"KEY", 3) == true)
	{
		index = true;
		index_name = GetNextIdentToken();
		if(_target != SQL_MYSQL)
		{
			Token::Change(cns, "CREATE INDEX", L"CREATE INDEX", 12);
			Append(index_name, " ON ", L" ON ", 4, cns);
			AppendCopy(index_name, table_name);
		}
	}
	else
		return false;
	if(primary == true || unique == true)
	{
		Token *clustered = GetNext("CLUSTERED", L"CLUSTERED", 9);
		Token *nonclustered = NULL;
		if(clustered == NULL)
			nonclustered = GetNext("NONCLUSTERED", L"NONCLUSTERED", 12);
		if(_target != SQL_SQL_SERVER)
		{
			Token::Remove(clustered);
			Token::Remove(nonclustered);
		}
	}
	Token *open = GetNextCharToken('(', L'(');
	if(open == NULL)
		return false;
	Book *cr_table_start = NULL;
	Book *cr_table_end = NULL;
	bool greenplum_distributed = false;
	if(_target == SQL_GREENPLUM)
	{
		cr_table_start = GetBookmark(BOOK_CT_START, table_name);
		cr_table_end = GetBookmark(BOOK_CTC_ALL_END, table_name);
		if(cr_table_start != NULL && cr_table_end != NULL && cr_table_end->distributed_by == false)
		{
			Append(cr_table_end->book, " DISTRIBUTED BY (", L" DISTRIBUTED BY (", 17, cr_table_start->book);
			greenplum_distributed = true;
		}
	}
	int count = 0;
	while(true)
	{
		Token *col = GetNextIdentToken();
		if(col == NULL)
			break;
		if(primary == true)
			pkcols.Add(col);
		if(greenplum_distributed == true)
		{
			if(count > 0)
				Append(cr_table_end->book, ", ", L", ", 2);
			AppendCopy(cr_table_end->book, col);
		}
		count++;
		Token *asc = GetNext("ASC", L"ASC", 3); 
		Token *desc = NULL;
		if(asc == NULL)
			desc = GetNext("DESC", L"DESC", 4);
		if(_target == SQL_ORACLE && index == false)
		{
			if(asc != NULL)
				Token::Remove(asc);
			if(desc != NULL)
				Comment(desc);
		}
		Token *next = GetNextToken();
		if(next == NULL)
			break;
		if(next->Compare(',', L',') == true)
			continue;
		PushBack(next);
		break;
	}
	Token *close = GetNextCharToken(')', L')');
	ParseKeyIndexOptions();
	if(inline_cns == true && primary == true && _target == SQL_ORACLE)
		Token::Remove(open, close);
	if(unique == false && index == true && inline_indexes != NULL)
	{
		inline_indexes->Add(cns, GetLastToken());
		Token *prev = GetPrevToken(cns);
		if(Token::Compare(prev, ',', L',') == true)
			Token::Remove(prev);
	}
	if(greenplum_distributed == true)
	{
		Append(cr_table_end->book, ")", L")", 1);
		cr_table_end->distributed_by = true;
	}
	return true;
}
bool SqlParser :: ParseKeyConstraint ( Token * , Token * table_name , Token * cns , ListW & pkcols , bool inline_cns , ListWM * inline_indexes ) { if ( cns == NULL ) return false ; bool primary = false ; bool unique = false ; bool unique_index = false ; bool index = false ; Token * index_name = NULL ; if ( cns -> Compare ( " " , L" " , 7 ) == true ) { ( void ) GetNextWordToken ( " " , L" " , 3 ) ; primary = true ; if ( _stmt_scope == SQL_STMT_ALTER_TABLE ) ALTER_TAB_STMS_STATS ( " " ) } else if ( cns -> Compare ( " " , L" " , 6 ) == true ) { unique = true ; Token * index = GetNextWordToken ( " " , L" " , 5 ) ; if ( index == NULL ) index = GetNextWordToken ( " " , L" " , 3 ) ; if ( index != NULL ) { unique_index = true ; index_name = GetNextIdentToken ( ) ; if ( _target != SQL_MYSQL ) { if ( index_name != NULL ) { Prepend ( cns , " " , L" " , 11 ) ; PrependCopy ( cns , index_name ) ; PrependNoFormat ( cns , " " , L" " , 1 ) ; Token :: Remove ( index_name ) ; } Token :: Remove ( index ) ; } } if ( _stmt_scope == SQL_STMT_ALTER_TABLE ) ALTER_TAB_STMS_STATS ( " " ) } else if ( cns -> Compare ( " " , L" " , 5 ) == true || cns -> Compare ( " " , L" " , 3 ) == true ) { index = true ; index_name = GetNextIdentToken ( ) ; if ( _target != SQL_MYSQL ) { Token :: Change ( cns , " " , L" " , 12 ) ; Append ( index_name , " " , L" " , 4 , cns ) ; AppendCopy ( index_name , table_name ) ; } } else return false ; if ( primary == true || unique == true ) { Token * clustered = GetNext ( " " , L" " , 9 ) ; Token * nonclustered = NULL ; if ( clustered == NULL ) nonclustered = GetNext ( " " , L" " , 12 ) ; if ( _target != SQL_SQL_SERVER ) { Token :: Remove ( clustered ) ; Token :: Remove ( nonclustered ) ; } } Token * open = GetNextCharToken ( ' ' , L' ' ) ; if ( open == NULL ) return false ; Book * cr_table_start = NULL ; Book * cr_table_end = NULL ; bool greenplum_distributed = false ; if ( _target == SQL_GREENPLUM ) { cr_table_start = GetBookmark ( BOOK_CT_START , table_name ) ; cr_table_end = GetBookmark ( BOOK_CTC_ALL_END , table_name ) ; if ( cr_table_start != NULL && cr_table_end != NULL && cr_table_end -> distributed_by == false ) { Append ( cr_table_end -> book , " " , L" " , 17 , cr_table_start -> book ) ; greenplum_distributed = true ; } } int count = 0 ; while ( true ) { Token * col = GetNextIdentToken ( ) ; if ( col == NULL ) break ; if ( primary == true ) pkcols . Add ( col ) ; if ( greenplum_distributed == true ) { if ( count > 0 ) Append ( cr_table_end -> book , " " , L" " , 2 ) ; AppendCopy ( cr_table_end -> book , col ) ; } count ++ ; Token * asc = GetNext ( " " , L" " , 3 ) ; Token * desc = NULL ; if ( asc == NULL ) desc = GetNext ( " " , L" " , 4 ) ; if ( _target == SQL_ORACLE && index == false ) { if ( asc != NULL ) Token :: Remove ( asc ) ; if ( desc != NULL ) Comment ( desc ) ; } Token * next = GetNextToken ( ) ; if ( next == NULL ) break ; if ( next -> Compare ( ' ' , L' ' ) == true ) continue ; PushBack ( next ) ; break ; } Token * close = GetNextCharToken ( ' ' , L' ' ) ; ParseKeyIndexOptions ( ) ; if ( inline_cns == true && primary == true && _target == SQL_ORACLE ) Token :: Remove ( open , close ) ; if ( unique == false && index == true && inline_indexes != NULL ) { inline_indexes -> Add ( cns , GetLastToken ( ) ) ; Token * prev = GetPrevToken ( cns ) ; if ( Token :: Compare ( prev , ' ' , L' ' ) == true ) Token :: Remove ( prev ) ; } if ( greenplum_distributed == true ) { Append ( cr_table_end -> book , " " , L" " , 1 ) ; cr_table_end -> distributed_by = true ; } return true ; }
Parse PRIMARY KEY, UNIQUE constraint clause, and INDEX/KEY in MySQL
Parse PRIMARY KEY UNIQUE constraint clause and INDEX / KEY in MySQL
/*alter*/ // MySQL UNIQUE INDEX clause // PRIMARY KEY /*Token *key */ // UNIQUE // Check for MySQL UNIQUE KEY or UNIQUE INDEX // if index/key name is specified use it as CONSTRAINT name // Remove INDEX or KEY keyword for other databases (UNIQUE constraint will be used) // MySQL INDEX or KEY for inline non-unique index // Standalone CREATE TABLE will be generated for other databases // In SQL Server PRIMARY and UNIQUE key can be CLUSTERED or NONCLUSTERED // CLUSTERED or NONCLUSTERED keyword can go for SQL Server // Remove for other databases // Get bookmarks to CREATE TABLE // Add DISTRIBUTED BY to CREATE TABLE for Greenplum // For Greenplum, add column to DISTRIBUTED BY in CREATE TABLE // For SQL Server PRIMARY KEY, for MySQL index next can be ASC DESC  // Oracle does not allow specifying ASC, DESC in key constraint, but if it is index it will be // moved to a separate CREATE INDEX, so ASC and DESC can be used // ASC is the default in index so just remove it // Leave if not comma // Parse index options // In inline constraint Oracle does not allow specifying column name again // Check for inline non-unique index in MySQL // Inline indexes will be moved, so delete comma at the end of previous column // Close DISTRIBUTED BY clause for Greenplum