sqlparser/helpers.cpp
// Add declarations for implicit record fields (for cursor loops)
Add declarations for implicit record fields (for cursor loops)
Add declarations for implicit record fields ( for cursor loops )
void SqlParser::DiscloseImplicitRecordVariables(Token *format)
{
	ListwmItem *item = _spl_implicit_rowtype_fields.GetFirst();
	Token *append = GetDeclarationAppend();
	Token *fmt = Nvl(_declare_format, format);
	while(item != NULL)
	{
		Token *cursor = (Token*)item->value;
		Token *var = (Token*)item->value2;
		Token var_last_part;
		var_last_part.len = var->len;
		var_last_part.str = var->str;
		TokenStr cur;
		TokenStr col;
		SplitIdentifierByLastPart(&var_last_part, cur, col, 2);
		APPEND_FMT(append, "\nDECLARE ", fmt);
		AppendCopy(append, var);
		ListwmItem *sel_item = _spl_declared_cursors_select_exp.GetFirst();
		const char *datatype_meta = NULL;
		while(sel_item != NULL)
		{
			Token *sel_cursor = (Token*)sel_item->value;
			Token *sel_col = (Token*)sel_item->value2;
			if(Token::Compare(cursor, sel_cursor))
			{
				if(sel_col->datatype_meta != NULL && Token::Compare(sel_col, &col))
				{
					datatype_meta = sel_col->datatype_meta;
					break;
				}
				else
				if(sel_col->table != NULL && TOKEN_CMPC(sel_col, '*'))
				{
					Token tcol;
					tcol.str = col.str.c_str();
					tcol.len = col.len;
					datatype_meta = GetMetaType(sel_col->table, &tcol);
					break;
				}
			}
			sel_item = sel_item->next;
		}
		if(datatype_meta != NULL)
		{
			TokenStr dt;
			APPENDSTR(dt, " ");
			dt.Append(datatype_meta, NULL, strlen(datatype_meta));
			AppendNoFormat(append, &dt);			
			APPEND(append, ";");
		}
		else
		{
			APPEND_FMT(append, " VARCHAR(200)", fmt);
			APPEND(append, "; -- Use -meta option to resolve the data type");
		}
		item = item->next;
	}
	item = _spl_implicit_rowtype_fetches.GetFirst();
	while(item != NULL)
	{
		Token *cursor = (Token*)item->value;
		Token *fetch_stmt = (Token*)item->value2;
		Token *format = (Token*)item->value3;
		ListwmItem *col_item = _spl_implicit_rowtype_fields.GetFirst();
		TokenStr into_cols;
		int cnt = 0;
		while(col_item != NULL)
		{
			Token *col_cursor = (Token*)col_item->value;
			Token *var = (Token*)col_item->value2;
			if(Token::Compare(cursor, col_cursor))
			{
				if(cnt > 0)
					APPENDSTR(into_cols, ", ");
				into_cols.Append(var);
				cnt++;
			}
			col_item = col_item->next;
		}
		AppendNoFormat(fetch_stmt, &into_cols);
		APPEND_NOFMT(fetch_stmt, ";");
		APPEND_FMT(fetch_stmt, "\n", format);
		item = item->next;
	}
	item = _spl_declared_cursors_select_first_exp.GetFirst();
	while(item != NULL)
	{
		Token *cursor = (Token*)item->value;
		Token *first_select_exp = (Token*)item->value2;
		if(first_select_exp == NULL || !TOKEN_CMPC(first_select_exp, '*')) 
		{
			item = item->next;
			continue;
		}
		ListwmItem *col_item = _spl_implicit_rowtype_fields.GetFirst();
		TokenStr cursor_cols;
		int cnt = 0;
		while(col_item != NULL)
		{
			Token *col_cursor = (Token*)col_item->value;
			Token *var = (Token*)col_item->value2;
			if(Token::Compare(cursor, col_cursor))
			{
				if(cnt > 0)
					APPENDSTR(cursor_cols, ", ");
				TokenStr cur;
				TokenStr col;
				Token var_src;
				var_src.len = var->len;
				var_src.str = var->str;
				SplitIdentifierByLastPart(&var_src, cur, col, 2);
				cursor_cols.Append(col);
				cnt++;
			}
			col_item = col_item->next;
		}
		Token::ChangeNoFormat(first_select_exp, cursor_cols);
		item = item->next;
	}		
}
void SqlParser :: DiscloseImplicitRecordVariables ( Token * format ) { ListwmItem * item = _spl_implicit_rowtype_fields . GetFirst ( ) ; Token * append = GetDeclarationAppend ( ) ; Token * fmt = Nvl ( _declare_format , format ) ; while ( item != NULL ) { Token * cursor = ( Token * ) item -> value ; Token * var = ( Token * ) item -> value2 ; Token var_last_part ; var_last_part . len = var -> len ; var_last_part . str = var -> str ; TokenStr cur ; TokenStr col ; SplitIdentifierByLastPart ( & var_last_part , cur , col , 2 ) ; APPEND_FMT ( append , " \n " , fmt ) ; AppendCopy ( append , var ) ; ListwmItem * sel_item = _spl_declared_cursors_select_exp . GetFirst ( ) ; const char * datatype_meta = NULL ; while ( sel_item != NULL ) { Token * sel_cursor = ( Token * ) sel_item -> value ; Token * sel_col = ( Token * ) sel_item -> value2 ; if ( Token :: Compare ( cursor , sel_cursor ) ) { if ( sel_col -> datatype_meta != NULL && Token :: Compare ( sel_col , & col ) ) { datatype_meta = sel_col -> datatype_meta ; break ; } else if ( sel_col -> table != NULL && TOKEN_CMPC ( sel_col , ' ' ) ) { Token tcol ; tcol . str = col . str . c_str ( ) ; tcol . len = col . len ; datatype_meta = GetMetaType ( sel_col -> table , & tcol ) ; break ; } } sel_item = sel_item -> next ; } if ( datatype_meta != NULL ) { TokenStr dt ; APPENDSTR ( dt , " " ) ; dt . Append ( datatype_meta , NULL , strlen ( datatype_meta ) ) ; AppendNoFormat ( append , & dt ) ; APPEND ( append , " " ) ; } else { APPEND_FMT ( append , " " , fmt ) ; APPEND ( append , " " ) ; } item = item -> next ; } item = _spl_implicit_rowtype_fetches . GetFirst ( ) ; while ( item != NULL ) { Token * cursor = ( Token * ) item -> value ; Token * fetch_stmt = ( Token * ) item -> value2 ; Token * format = ( Token * ) item -> value3 ; ListwmItem * col_item = _spl_implicit_rowtype_fields . GetFirst ( ) ; TokenStr into_cols ; int cnt = 0 ; while ( col_item != NULL ) { Token * col_cursor = ( Token * ) col_item -> value ; Token * var = ( Token * ) col_item -> value2 ; if ( Token :: Compare ( cursor , col_cursor ) ) { if ( cnt > 0 ) APPENDSTR ( into_cols , " " ) ; into_cols . Append ( var ) ; cnt ++ ; } col_item = col_item -> next ; } AppendNoFormat ( fetch_stmt , & into_cols ) ; APPEND_NOFMT ( fetch_stmt , " " ) ; APPEND_FMT ( fetch_stmt , " \n " , format ) ; item = item -> next ; } item = _spl_declared_cursors_select_first_exp . GetFirst ( ) ; while ( item != NULL ) { Token * cursor = ( Token * ) item -> value ; Token * first_select_exp = ( Token * ) item -> value2 ; if ( first_select_exp == NULL || ! TOKEN_CMPC ( first_select_exp , ' ' ) ) { item = item -> next ; continue ; } ListwmItem * col_item = _spl_implicit_rowtype_fields . GetFirst ( ) ; TokenStr cursor_cols ; int cnt = 0 ; while ( col_item != NULL ) { Token * col_cursor = ( Token * ) col_item -> value ; Token * var = ( Token * ) col_item -> value2 ; if ( Token :: Compare ( cursor , col_cursor ) ) { if ( cnt > 0 ) APPENDSTR ( cursor_cols , " " ) ; TokenStr cur ; TokenStr col ; Token var_src ; var_src . len = var -> len ; var_src . str = var -> str ; SplitIdentifierByLastPart ( & var_src , cur , col , 2 ) ; cursor_cols . Append ( col ) ; cnt ++ ; } col_item = col_item -> next ; } Token :: ChangeNoFormat ( first_select_exp , cursor_cols ) ; item = item -> next ; } }
Add declarations for implicit record fields (for cursor loops)
Add declarations for implicit record fields ( for cursor loops )
// Add declaration for each variable // Separate cursor and column names // Try to define the data type from SELECT list expressions // For SELECT * FROM single table, table name may be resolved // Add column list to all generated fetch statements // Find columns of this cursor only // Add column list to cursor declaration that use SELECT * FROM instead of explicit column list // Find columns of this cursor only // Separate cursor and column names // Replace * with column list