|
27 | 27 | int gbl_lightweight_rename = 0; |
28 | 28 | int gbl_transactional_drop_plus_rename = 1; |
29 | 29 |
|
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 | | - |
53 | 30 | int do_rename_table(struct ireq *iq, struct schema_change_type *s, |
54 | 31 | tran_type *tran) |
55 | 32 | { |
56 | | - struct dbtable *db; |
| 33 | + struct dbtable *db, *colliding_db; |
57 | 34 | iq->usedb = db = s->db = get_dbtable_by_name(s->tablename); |
58 | 35 | if (db == NULL) { |
59 | 36 | sc_client_error(s, "Table doesn't exist"); |
60 | 37 | return SC_TABLE_DOESNOT_EXIST; |
61 | 38 | } |
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))) { |
65 | 48 | sc_client_error(s, "New table name exists"); |
66 | 49 | return SC_TABLE_ALREADY_EXIST; |
67 | 50 | } |
@@ -117,6 +100,12 @@ int finalize_rename_table(struct ireq *iq, struct schema_change_type *s, |
117 | 100 | return -1; |
118 | 101 | } |
119 | 102 |
|
| 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 | + |
120 | 109 | char *newname = strdup(s->newtable); |
121 | 110 | if (!newname) { |
122 | 111 | sc_errf(s, "strdup error\n"); |
|
0 commit comments