13
13
#include < Parsers/parseQuery.h>
14
14
#include < Storages/MutableSupport.h>
15
15
#include < Storages/Transaction/SchemaBuilder.h>
16
+ #include < Storages/Transaction/SchemaBuilder-internal.h>
16
17
#include < Storages/Transaction/TMTContext.h>
17
18
#include < Storages/Transaction/TypeMapping.h>
18
19
@@ -26,84 +27,6 @@ namespace ErrorCodes
26
27
extern const int DDL_ERROR;
27
28
}
28
29
29
-
30
- constexpr char tmpNamePrefix[] = " _tiflash_tmp_" ;
31
-
32
- struct TmpTableNameGenerator
33
- {
34
- using TableName = std::pair<String, String>;
35
- TableName operator ()(const TableName & name) { return std::make_pair (name.first , String (tmpNamePrefix) + name.second ); }
36
- };
37
-
38
- struct TmpColNameGenerator
39
- {
40
- String operator ()(const String & name) { return String (tmpNamePrefix) + name; }
41
- };
42
-
43
- // CyclicRenameResolver resolves cyclic table rename and column rename.
44
- // TmpNameGenerator rename current name to a temp name that will not conflict with other names.
45
- template <typename Name_, typename TmpNameGenerator>
46
- struct CyclicRenameResolver
47
- {
48
- using Name = Name_;
49
- using NamePair = std::pair<Name, Name>;
50
- using NameMap = std::map<Name, Name>;
51
- using NameSet = std::set<Name>;
52
-
53
- // visited records which name has been processed.
54
- NameSet visited;
55
- TmpNameGenerator name_gen;
56
-
57
- // We will not ensure correctness if we call it multiple times, so we make it a rvalue call.
58
- std::vector<NamePair> resolve (const NameMap & rename_map) &&
59
- {
60
- std::vector<NamePair> result;
61
- for (auto it = rename_map.begin (); it != rename_map.end (); it++)
62
- {
63
- if (!visited.count (it->first ))
64
- {
65
- resolveImpl (rename_map, it, result);
66
- }
67
- }
68
- return result;
69
- }
70
-
71
- private:
72
- NamePair resolveImpl (const NameMap & rename_map, typename NameMap::const_iterator & it, std::vector<NamePair> & result)
73
- {
74
- Name target_name = it->second ;
75
- Name origin_name = it->first ;
76
- visited.insert (it->first );
77
- auto next_it = rename_map.find (target_name);
78
- if (next_it == rename_map.end ())
79
- {
80
- // The target name does not exist, so we can rename it directly.
81
- result.push_back (NamePair (origin_name, target_name));
82
- return NamePair ();
83
- }
84
- else if (visited.find (target_name) != visited.end ())
85
- {
86
- // The target name is visited, so this is a cyclic rename.
87
- auto tmp_name = name_gen (target_name);
88
- result.push_back (NamePair (target_name, tmp_name));
89
- result.push_back (NamePair (origin_name, target_name));
90
- return NamePair (target_name, tmp_name);
91
- }
92
- else
93
- {
94
- // The target name is in rename map, so we continue to resolve it.
95
- auto pair = resolveImpl (rename_map, next_it, result);
96
- if (pair.first == origin_name)
97
- {
98
- origin_name = pair.second ;
99
- }
100
- result.push_back (NamePair (origin_name, target_name));
101
- return pair;
102
- }
103
- }
104
- };
105
-
106
-
107
30
inline void setAlterCommandColumn (Logger * log, AlterCommand & command, const ColumnInfo & column_info)
108
31
{
109
32
command.column_name = column_info.name ;
@@ -152,7 +75,8 @@ inline std::vector<AlterCommands> detectSchemaChanges(Logger * log, const TableI
152
75
}
153
76
154
77
{
155
- std::map<String, String> rename_map;
78
+ using Resolver = CyclicRenameResolver<String, TmpColNameGenerator>;
79
+ typename Resolver::NameMap rename_map;
156
80
// / rename columns.
157
81
for (const auto & orig_column_info : orig_table_info.columns )
158
82
{
@@ -167,7 +91,7 @@ inline std::vector<AlterCommands> detectSchemaChanges(Logger * log, const TableI
167
91
}
168
92
}
169
93
170
- auto rename_result = CyclicRenameResolver<String, TmpColNameGenerator> ().resolve (rename_map);
94
+ typename Resolver::NamePairs rename_result = Resolver ().resolve (std::move ( rename_map) );
171
95
for (const auto & rename_pair : rename_result)
172
96
{
173
97
AlterCommands rename_commands;
@@ -189,7 +113,7 @@ inline std::vector<AlterCommands> detectSchemaChanges(Logger * log, const TableI
189
113
const auto & column_info
190
114
= std::find_if (table_info.columns .begin (), table_info.columns .end (), [&](const ColumnInfo & column_info_) {
191
115
if (column_info_.id == orig_column_info.id && column_info_.name != orig_column_info.name )
192
- LOG_ERROR (log , " detect column " << orig_column_info.name << " rename to " << column_info_.name );
116
+ LOG_INFO (log , " detect column " << orig_column_info.name << " rename to " << column_info_.name );
193
117
194
118
return column_info_.id == orig_column_info.id
195
119
&& (column_info_.tp != orig_column_info.tp || column_info_.hasNotNullFlag () != orig_column_info.hasNotNullFlag ());
@@ -200,7 +124,7 @@ inline std::vector<AlterCommands> detectSchemaChanges(Logger * log, const TableI
200
124
AlterCommand command;
201
125
// Type changed column.
202
126
command.type = AlterCommand::MODIFY_COLUMN;
203
- // Alter column with old name.
127
+ // Alter column with new column info
204
128
setAlterCommandColumn (log , command, *column_info);
205
129
alter_commands.emplace_back (std::move (command));
206
130
}
@@ -798,7 +722,7 @@ void SchemaBuilder<Getter>::alterAndRenameTables(std::vector<std::pair<TableInfo
798
722
}
799
723
}
800
724
801
- auto result = Resolver ().resolve (rename_map);
725
+ typename Resolver::NamePairs result = Resolver ().resolve (std::move ( rename_map) );
802
726
for (const auto & rename_pair : result)
803
727
{
804
728
applyRenameTableImpl (rename_pair.first .first , rename_pair.second .first , rename_pair.first .second , rename_pair.second .second );
0 commit comments