Skip to content

Commit ba57646

Browse files
morgandoakshatsikarwar
authored andcommitted
Check for rename collisions in finalize
Signed-off-by: mdouglas47 <[email protected]>
1 parent f48a003 commit ba57646

File tree

4 files changed

+32
-27
lines changed

4 files changed

+32
-27
lines changed

schemachange/sc_rename_table.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,41 +27,24 @@
2727
int gbl_lightweight_rename = 0;
2828
int gbl_transactional_drop_plus_rename = 1;
2929

30-
static int colliding_db_dropped_prior_in_my_tran(const struct schema_change_type * rename_sc)
31-
{
32-
const struct schema_change_type * sc = rename_sc;
33-
const char * const new_name = rename_sc->newtable;
34-
while (sc) {
35-
if (strcasecmp(sc->tablename, new_name) == 0 && sc->kind == SC_DROPTABLE) {
36-
return 1;
37-
}
38-
sc = sc->sc_next;
39-
}
40-
return 0;
41-
}
42-
43-
static int fatal_naming_collision(const struct dbtable *colliding_db, const struct dbtable *rename_db,
44-
const struct schema_change_type * rename_sc)
45-
{
46-
if (!colliding_db) { return 0; }
47-
else if (gbl_lightweight_rename && (rename_db == colliding_db)) { return 0; }
48-
else if (gbl_transactional_drop_plus_rename && (rename_sc->kind == SC_RENAMETABLE)
49-
&& colliding_db_dropped_prior_in_my_tran(rename_sc)) { return 0; }
50-
return 1;
51-
}
52-
5330
int do_rename_table(struct ireq *iq, struct schema_change_type *s,
5431
tran_type *tran)
5532
{
56-
struct dbtable *db;
33+
struct dbtable *db, *colliding_db;
5734
iq->usedb = db = s->db = get_dbtable_by_name(s->tablename);
5835
if (db == NULL) {
5936
sc_client_error(s, "Table doesn't exist");
6037
return SC_TABLE_DOESNOT_EXIST;
6138
}
62-
63-
const struct dbtable *colliding_db = get_dbtable_by_name(s->newtable);
64-
if (fatal_naming_collision(colliding_db, db, s)) {
39+
/* If transactional_drop_plus_rename is enabled then we need to
40+
* wait until finalize to check for colliding tables: If we check
41+
* for colliding tables now, we incorrectly error on tables that were
42+
* dropped prior in our transaction. If we check in finalize, those tables
43+
* will have already been dropped.
44+
*/
45+
if (!gbl_transactional_drop_plus_rename
46+
&& ((colliding_db = get_dbtable_by_name(s->newtable)) != NULL)
47+
&& (!gbl_lightweight_rename || (db != colliding_db))) {
6548
sc_client_error(s, "New table name exists");
6649
return SC_TABLE_ALREADY_EXIST;
6750
}
@@ -117,6 +100,12 @@ int finalize_rename_table(struct ireq *iq, struct schema_change_type *s,
117100
return -1;
118101
}
119102

103+
if (gbl_transactional_drop_plus_rename
104+
&& get_dbtable_by_name(s->newtable)) {
105+
sc_client_error(s, "New table name exists");
106+
return SC_TABLE_ALREADY_EXIST;
107+
}
108+
120109
char *newname = strdup(s->newtable);
121110
if (!newname) {
122111
sc_errf(s, "strdup error\n");

tests/renametable.test/reqoutput.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,7 @@
123123
[drop table t2] rc 0
124124
[alter table t2 rename to t] failed with rc 240 New table name exists
125125
[alter table t2 rename to t2] failed with rc 240 New table name exists
126+
[begin] rc 0
127+
[alter table t rename to dummy] rc 0
128+
[alter table t2 rename to t] rc 0
129+
[commit] rc 0

tests/renametable.test/reqoutput_lightweight.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,7 @@
123123
[drop table t2] rc 0
124124
[alter table t2 rename to t] failed with rc -3 New table name already exists
125125
[alter table t2 rename to t2] failed with rc -3 New table name already exists
126+
[commit] failed with rc -3 New table name already exists
127+
[begin] rc 0
128+
[alter table t rename to dummy] rc 0
129+
[alter table t2 rename to t] rc 0

tests/renametable.test/runit

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ cdb2sql ${CDB2_OPTIONS} $dbnm default "alter table t2 rename to t" &>> $OUT
133133
# Rename to our own name
134134
cdb2sql ${CDB2_OPTIONS} $dbnm default "alter table t2 rename to t2" &>> $OUT
135135

136+
# Rename after renaming table with target name in txn
137+
cat <<EOF | cdb2sql ${CDB2_OPTIONS} $dbnm default - >> $OUT 2>&1
138+
begin
139+
alter table t rename to dummy\$\$
140+
alter table t2 rename to t\$\$
141+
commit
142+
EOF
143+
136144
df=$(diff $OUT $EXP)
137145
if [ $? -ne 0 ] ; then
138146
echo " ^^^^^^^^^^^^"

0 commit comments

Comments
 (0)