Merge lp:~vkolesnikov/pbxt/pbxt-bug-378222 into lp:pbxt
- pbxt-bug-378222
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~vkolesnikov/pbxt/pbxt-bug-378222 |
Merge into: | lp:pbxt |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~vkolesnikov/pbxt/pbxt-bug-378222 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PBXT Core | Pending | ||
Review via email: mp+7376@code.launchpad.net |
Commit message
Description of the change
Paul McCullagh (paul-mccullagh) wrote : | # |
Vladimir Kolesnikov (vkolesnikov) wrote : | # |
This was my first idea too, but xt_use_table requires self->st_database
to be inited which is done in xt_ue_database() so I put this code right
after the call to xt_use_database (and xt_use_database itself doesn't
seem to be good place too). Of course I can copy some code from
xt_use_database and put it before the use_table but I thought it's not a
good idea.
Paul McCullagh wrote:
> Hi Vlad,
>
> This patch looks good. Just one thing: how about doing this in
> xt_tab_init_db()?
>
> I think this would be more efficient.
>
> On Jun 12, 2009, at 4:40 PM, Vladimir Kolesnikov wrote:
>
>
>> === modified file 'src/database_
>> --- src/database_xt.cc 2009-05-28 15:17:16 +0000
>> +++ src/database_xt.cc 2009-06-12 14:29:30 +0000
>> @@ -616,7 +616,9 @@
>> xtPublic void xt_open_
>> multi_path)
>> {
>> XTDatabaseHPtr db;
>> -
>> + XTTableDescRec desc;
>> + XTPathStr table_path;
>> +
>> /* We cannot get a database, without unusing the current
>> * first. The reason is that the restart process will
>> * partially set the current database!
>> @@ -625,7 +627,18 @@
>> db = xt_get_
>> pushr_(
>> xt_use_
>> - freer_(); // xt_heap_
>> +
>> + xt_describe_
>> + pushr_(
>> + while (xt_describe_
>> + xt_strcpy(PATH_MAX, table_path.ps_path, desc.td_
>> + xt_add_
>> + xt_strcat(PATH_MAX, table_path.ps_path, desc.td_tab_name);
>> + xt_heap_
>> FALSE, NULL));
>> + }
>> +
>> + freer_(); // xt_describe_
>> + freer_(); // xt_heap_
>> }
>>
>>
>
>
>
> --
> Paul McCullagh
> PrimeBase Technologies
> www.primebase.org
> www.blobstreami
> pbxt.blogspot.com
>
>
>
>
--
--
Best Regards,
Vladimir
Paul McCullagh (paul-mccullagh) wrote : | # |
I think you could try: xt_use_
Because lock on db->db_tables is not required anyway.
On Jun 16, 2009, at 12:18 PM, Vladimir Kolesnikov wrote:
> This was my first idea too, but xt_use_table requires self-
> >st_database
> to be inited which is done in xt_ue_database() so I put this code
> right
> after the call to xt_use_database (and xt_use_database itself doesn't
> seem to be good place too). Of course I can copy some code from
> xt_use_database and put it before the use_table but I thought it's
> not a
> good idea.
>
> Paul McCullagh wrote:
>> Hi Vlad,
>>
>> This patch looks good. Just one thing: how about doing this in
>> xt_tab_init_db()?
>>
>> I think this would be more efficient.
>>
>> On Jun 12, 2009, at 4:40 PM, Vladimir Kolesnikov wrote:
>>
>>
>>> === modified file 'src/database_
>>> --- src/database_xt.cc 2009-05-28 15:17:16 +0000
>>> +++ src/database_xt.cc 2009-06-12 14:29:30 +0000
>>> @@ -616,7 +616,9 @@
>>> xtPublic void xt_open_
>>> multi_path)
>>> {
>>> XTDatabaseHPtr db;
>>> -
>>> + XTTableDescRec desc;
>>> + XTPathStr table_path;
>>> +
>>> /* We cannot get a database, without unusing the current
>>> * first. The reason is that the restart process will
>>> * partially set the current database!
>>> @@ -625,7 +627,18 @@
>>> db = xt_get_
>>> pushr_(
>>> xt_use_
>>> - freer_(); // xt_heap_
>>> +
>>> + xt_describe_
>>> + pushr_(
>>> + while (xt_describe_
>>> + xt_strcpy(PATH_MAX, table_path.ps_path, desc.td_tab_path-
>>> >tp_path);
>>> + xt_add_
>>> + xt_strcat(PATH_MAX, table_path.ps_path, desc.td_tab_name);
>>> + xt_heap_
>>> FALSE, NULL));
>>> + }
>>> +
>>> + freer_(); // xt_describe_
>>> + freer_(); // xt_heap_
>>> }
>>>
>>>
>>
>>
>>
>> --
>> Paul McCullagh
>> PrimeBase Technologies
>> www.primebase.org
>> www.blobstreami
>> pbxt.blogspot.com
>>
>>
>>
>>
>
>
> --
> --
> Best Regards,
> Vladimir
>
> https:/
> 7376
> Your team PBXT Core is subscribed to branch lp:pbxt.
--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreami
pbxt.blogspot.com
Vladimir Kolesnikov (vkolesnikov) wrote : | # |
pushed the change
Paul McCullagh wrote:
> I think you could try: xt_use_
>
> Because lock on db->db_tables is not required anyway.
>
> On Jun 16, 2009, at 12:18 PM, Vladimir Kolesnikov wrote:
>
>
>> This was my first idea too, but xt_use_table requires self-
>>
>>> st_database
>>>
>> to be inited which is done in xt_ue_database() so I put this code
>> right
>> after the call to xt_use_database (and xt_use_database itself doesn't
>> seem to be good place too). Of course I can copy some code from
>> xt_use_database and put it before the use_table but I thought it's
>> not a
>> good idea.
>>
>> Paul McCullagh wrote:
>>
>>> Hi Vlad,
>>>
>>> This patch looks good. Just one thing: how about doing this in
>>> xt_tab_init_db()?
>>>
>>> I think this would be more efficient.
>>>
>>> On Jun 12, 2009, at 4:40 PM, Vladimir Kolesnikov wrote:
>>>
>>>
>>>
>>>> === modified file 'src/database_
>>>> --- src/database_xt.cc 2009-05-28 15:17:16 +0000
>>>> +++ src/database_xt.cc 2009-06-12 14:29:30 +0000
>>>> @@ -616,7 +616,9 @@
>>>> xtPublic void xt_open_
>>>> multi_path)
>>>> {
>>>> XTDatabaseHPtr db;
>>>> -
>>>> + XTTableDescRec desc;
>>>> + XTPathStr table_path;
>>>> +
>>>> /* We cannot get a database, without unusing the current
>>>> * first. The reason is that the restart process will
>>>> * partially set the current database!
>>>> @@ -625,7 +627,18 @@
>>>> db = xt_get_
>>>> pushr_(
>>>> xt_use_
>>>> - freer_(); // xt_heap_
>>>> +
>>>> + xt_describe_
>>>> + pushr_(
>>>> + while (xt_describe_
>>>> + xt_strcpy(PATH_MAX, table_path.ps_path, desc.td_tab_path-
>>>>
>>>>> tp_path);
>>>>>
>>>> + xt_add_
>>>> + xt_strcat(PATH_MAX, table_path.ps_path, desc.td_tab_name);
>>>> + xt_heap_
>>>> FALSE, NULL));
>>>> + }
>>>> +
>>>> + freer_(); // xt_describe_
>>>> + freer_(); // xt_heap_
>>>> }
>>>>
>>>>
>>>>
>>>
>>> --
>>> Paul McCullagh
>>> PrimeBase Technologies
>>> www.primebase.org
>>> www.blobstreami
>>> pbxt.blogspot.com
>>>
>>>
>>>
>>>
>>>
>> --
>> --
>> Best Regards,
>> Vladimir
>>
>> https:/
>> 7376
>> Your team PBXT Core is subscribed to branch lp:pbxt.
>>
>
>
>
> --
> Paul McCullagh
> PrimeBase Technologies
> www.primebase.org
> www.blobstreami
> pbxt.blogspot.com
>
>
>
>
--
--
Best Regards,
Vladimir
- 658. By Paul McCullagh
-
Merged RN246
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2009-06-10 16:26:33 +0000 |
3 | +++ ChangeLog 2009-06-12 14:29:30 +0000 |
4 | @@ -3,6 +3,8 @@ |
5 | |
6 | ------- 1.0.08 RC - Not yet released |
7 | |
8 | +RN246: Fixed bug #378222: Drop sakila causes error: Cannot delete or update a parent row: a foreign key constraint fails |
9 | + |
10 | RN245: Fixed bug #379315: Inconsistent behavior of DELETE IGNORE and FK constraint |
11 | |
12 | RN244: Fixed a recovery problem: during the recovery of "record modified" action the table was updated before the old index entries were removed; then the xres_remove_index_entries was supplied the new record which lead to incorrect index update |
13 | |
14 | === modified file 'src/database_xt.cc' |
15 | --- src/database_xt.cc 2009-05-28 15:17:16 +0000 |
16 | +++ src/database_xt.cc 2009-06-12 14:29:30 +0000 |
17 | @@ -616,7 +616,9 @@ |
18 | xtPublic void xt_open_database(XTThreadPtr self, char *path, xtBool multi_path) |
19 | { |
20 | XTDatabaseHPtr db; |
21 | - |
22 | + XTTableDescRec desc; |
23 | + XTPathStr table_path; |
24 | + |
25 | /* We cannot get a database, without unusing the current |
26 | * first. The reason is that the restart process will |
27 | * partially set the current database! |
28 | @@ -625,7 +627,18 @@ |
29 | db = xt_get_database(self, path, multi_path); |
30 | pushr_(xt_heap_release, db); |
31 | xt_use_database(self, db, XT_FOR_USER); |
32 | - freer_(); // xt_heap_release(self, db); |
33 | + |
34 | + xt_describe_tables_init(self, db, &desc); |
35 | + pushr_(xt_describe_tables_exit, &desc); |
36 | + while (xt_describe_tables_next(self, &desc)) { |
37 | + xt_strcpy(PATH_MAX, table_path.ps_path, desc.td_tab_path->tp_path); |
38 | + xt_add_dir_char(PATH_MAX, table_path.ps_path); |
39 | + xt_strcat(PATH_MAX, table_path.ps_path, desc.td_tab_name); |
40 | + xt_heap_release(self, xt_use_table(self, &table_path, FALSE, FALSE, NULL)); |
41 | + } |
42 | + |
43 | + freer_(); // xt_describe_tables_exit(self, desc); |
44 | + freer_(); // xt_heap_release(self, db); |
45 | } |
46 | |
47 | /* This function can only be called if you do not already have a database in |
48 | |
49 | === modified file 'src/datadic_xt.cc' |
50 | --- src/datadic_xt.cc 2009-05-19 15:22:26 +0000 |
51 | +++ src/datadic_xt.cc 2009-06-12 14:29:30 +0000 |
52 | @@ -650,7 +650,7 @@ |
53 | int parseKeyAction(XTThreadPtr self); |
54 | void parseCreateTable(XTThreadPtr self); |
55 | void parseAddTableItem(XTThreadPtr self); |
56 | - void parseQualifiedName(XTThreadPtr self, char *name); |
57 | + void parseQualifiedName(XTThreadPtr self, char *parent_name, char *name); |
58 | void parseTableName(XTThreadPtr self, bool alterTable); |
59 | void parseExpression(XTThreadPtr self, bool allow_reserved); |
60 | void parseBrackets(XTThreadPtr self); |
61 | @@ -720,7 +720,7 @@ |
62 | } |
63 | virtual void addListedColumn(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(index_col_name)) { |
64 | } |
65 | - virtual void setReferencedTable(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(ref_table)) { |
66 | + virtual void setReferencedTable(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(ref_schema), char *XT_UNUSED(ref_table)) { |
67 | } |
68 | virtual void addReferencedColumn(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(index_col_name)) { |
69 | } |
70 | @@ -870,7 +870,7 @@ |
71 | if (pt_current->isKeyWord("CONSTRAINT")) { |
72 | pt_current = pt_tokenizer->nextToken(self); |
73 | if (pt_current->isIdentifier()) |
74 | - parseQualifiedName(self, name); |
75 | + parseQualifiedName(self, NULL, name); |
76 | } |
77 | |
78 | if (pt_current->isReservedWord(XT_TK_PRIMARY)) { |
79 | @@ -985,13 +985,15 @@ |
80 | char name[XT_IDENTIFIER_NAME_SIZE]; |
81 | |
82 | pt_current = pt_tokenizer->nextToken(self); |
83 | - parseQualifiedName(self, name); |
84 | + parseQualifiedName(self, NULL, name); |
85 | moveColumn(self, name); |
86 | } |
87 | } |
88 | |
89 | -void XTParseTable::parseQualifiedName(XTThreadPtr self, char *name) |
90 | +void XTParseTable::parseQualifiedName(XTThreadPtr self, char *parent_name, char *name) |
91 | { |
92 | + if (parent_name) |
93 | + parent_name[0] = '\0'; |
94 | /* Should be an identifier by I have this example: |
95 | * CREATE TABLE t1 ( comment CHAR(32) ASCII NOT NULL, koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL default '' ) CHARSET=latin5; |
96 | * |
97 | @@ -1001,6 +1003,8 @@ |
98 | raiseError(self, pt_current, XT_ERR_ID_TOO_LONG); |
99 | pt_current = pt_tokenizer->nextToken(self); |
100 | while (pt_current->isKeyWord(".")) { |
101 | + if (parent_name) |
102 | + xt_strcpy(XT_IDENTIFIER_NAME_SIZE,parent_name, name); |
103 | pt_current = pt_tokenizer->nextToken(self); |
104 | /* Accept anything after the DOT! */ |
105 | if (pt_current->getString(name, XT_IDENTIFIER_NAME_SIZE) >= XT_IDENTIFIER_NAME_SIZE) |
106 | @@ -1013,7 +1017,7 @@ |
107 | { |
108 | char name[XT_IDENTIFIER_NAME_SIZE]; |
109 | |
110 | - parseQualifiedName(self, name); |
111 | + parseQualifiedName(self, NULL, name); |
112 | setTableName(self, name, alterTable); |
113 | } |
114 | |
115 | @@ -1022,7 +1026,7 @@ |
116 | char col_name[XT_IDENTIFIER_NAME_SIZE]; |
117 | |
118 | // column_definition |
119 | - parseQualifiedName(self, col_name); |
120 | + parseQualifiedName(self, NULL, col_name); |
121 | addColumn(self, col_name, old_col_name); |
122 | parseDataType(self); |
123 | |
124 | @@ -1122,7 +1126,7 @@ |
125 | pt_current->expectKeyWord(self, "("); |
126 | do { |
127 | pt_current = pt_tokenizer->nextToken(self); |
128 | - parseQualifiedName(self, name); |
129 | + parseQualifiedName(self, NULL, name); |
130 | addListedColumn(self, name); |
131 | cols++; |
132 | if (index_cols) { |
133 | @@ -1146,19 +1150,20 @@ |
134 | int on_delete = XT_KEY_ACTION_DEFAULT; |
135 | int on_update = XT_KEY_ACTION_DEFAULT; |
136 | char name[XT_IDENTIFIER_NAME_SIZE]; |
137 | + char parent_name[XT_IDENTIFIER_NAME_SIZE]; |
138 | u_int cols = 0; |
139 | |
140 | // REFERENCES tbl_name |
141 | pt_current = pt_tokenizer->nextToken(self, "REFERENCES", pt_current); |
142 | - parseQualifiedName(self, name); |
143 | - setReferencedTable(self, name); |
144 | + parseQualifiedName(self, parent_name, name); |
145 | + setReferencedTable(self, parent_name[0] ? parent_name : NULL, name); |
146 | |
147 | // [ (index_col_name,...) ] |
148 | if (pt_current->isKeyWord("(")) { |
149 | pt_current->expectKeyWord(self, "("); |
150 | do { |
151 | pt_current = pt_tokenizer->nextToken(self); |
152 | - parseQualifiedName(self, name); |
153 | + parseQualifiedName(self, NULL, name); |
154 | addReferencedColumn(self, name); |
155 | cols++; |
156 | if (cols > req_cols) |
157 | @@ -1230,7 +1235,7 @@ |
158 | if (pt_current->isReservedWord(XT_TK_COLUMN)) |
159 | pt_current = pt_tokenizer->nextToken(self); |
160 | |
161 | - parseQualifiedName(self, old_col_name); |
162 | + parseQualifiedName(self, NULL, old_col_name); |
163 | parseColumnDefinition(self, old_col_name); |
164 | parseMoveColumn(self); |
165 | } |
166 | @@ -1262,7 +1267,7 @@ |
167 | else { |
168 | if (pt_current->isReservedWord(XT_TK_COLUMN)) |
169 | pt_current = pt_tokenizer->nextToken(self); |
170 | - parseQualifiedName(self, name); |
171 | + parseQualifiedName(self, NULL, name); |
172 | dropColumn(self, name); |
173 | } |
174 | } |
175 | @@ -1270,7 +1275,7 @@ |
176 | pt_current = pt_tokenizer->nextToken(self); |
177 | if (pt_current->isKeyWord("TO")) |
178 | pt_current = pt_tokenizer->nextToken(self); |
179 | - parseQualifiedName(self, name); |
180 | + parseQualifiedName(self, NULL, name); |
181 | } |
182 | else |
183 | /* Just ignore the syntax until the next , */ |
184 | @@ -1295,7 +1300,7 @@ |
185 | else if (pt_current->isKeyWord("SPACIAL")) |
186 | pt_current = pt_tokenizer->nextToken(self); |
187 | pt_current = pt_tokenizer->nextToken(self, "INDEX", pt_current); |
188 | - parseQualifiedName(self, name); |
189 | + parseQualifiedName(self, NULL, name); |
190 | optionalIndexType(self); |
191 | pt_current = pt_tokenizer->nextToken(self, "ON", pt_current); |
192 | parseTableName(self, true); |
193 | @@ -1310,7 +1315,7 @@ |
194 | |
195 | pt_current = pt_tokenizer->nextToken(self, "DROP", pt_current); |
196 | pt_current = pt_tokenizer->nextToken(self, "INDEX", pt_current); |
197 | - parseQualifiedName(self, name); |
198 | + parseQualifiedName(self, NULL, name); |
199 | pt_current = pt_tokenizer->nextToken(self, "ON", pt_current); |
200 | parseTableName(self, true); |
201 | dropConstraint(self, name, XT_DD_INDEX); |
202 | @@ -1351,7 +1356,7 @@ |
203 | virtual void addConstraint(XTThreadPtr self, char *name, u_int type, bool lastColumn); |
204 | virtual void dropConstraint(XTThreadPtr self, char *name, u_int type); |
205 | virtual void addListedColumn(XTThreadPtr self, char *index_col_name); |
206 | - virtual void setReferencedTable(XTThreadPtr self, char *ref_table); |
207 | + virtual void setReferencedTable(XTThreadPtr self, char *ref_schema, char *ref_table); |
208 | virtual void addReferencedColumn(XTThreadPtr self, char *index_col_name); |
209 | virtual void setActions(XTThreadPtr self, int on_delete, int on_update); |
210 | |
211 | @@ -1546,23 +1551,31 @@ |
212 | } |
213 | } |
214 | |
215 | -void XTCreateTable::setReferencedTable(XTThreadPtr self, char *ref_table) |
216 | +void XTCreateTable::setReferencedTable(XTThreadPtr self, char *ref_schema, char *ref_table) |
217 | { |
218 | XTDDForeignKey *fk = (XTDDForeignKey *) ct_curr_constraint; |
219 | char path[PATH_MAX]; |
220 | |
221 | - xt_strcpy(PATH_MAX, path, ct_tab_path->ps_path); |
222 | - xt_remove_last_name_of_path(path); |
223 | - if (ct_convert) { |
224 | - char buffer[XT_IDENTIFIER_NAME_SIZE]; |
225 | - size_t len; |
226 | - |
227 | - myxt_static_convert_identifier(self, ct_charset, ref_table, buffer, XT_IDENTIFIER_NAME_SIZE); |
228 | - len = strlen(path); |
229 | - myxt_static_convert_table_name(self, buffer, &path[len], PATH_MAX - len); |
230 | - } |
231 | - else |
232 | + if (ref_schema) { |
233 | + xt_strcpy(PATH_MAX,path, "."); |
234 | + xt_add_dir_char(PATH_MAX, path); |
235 | + xt_strcat(PATH_MAX, path, ref_schema); |
236 | + xt_add_dir_char(PATH_MAX, path); |
237 | xt_strcat(PATH_MAX, path, ref_table); |
238 | + } else { |
239 | + xt_strcpy(PATH_MAX, path, ct_tab_path->ps_path); |
240 | + xt_remove_last_name_of_path(path); |
241 | + if (ct_convert) { |
242 | + char buffer[XT_IDENTIFIER_NAME_SIZE]; |
243 | + size_t len; |
244 | + |
245 | + myxt_static_convert_identifier(self, ct_charset, ref_table, buffer, XT_IDENTIFIER_NAME_SIZE); |
246 | + len = strlen(path); |
247 | + myxt_static_convert_table_name(self, buffer, &path[len], PATH_MAX - len); |
248 | + } |
249 | + else |
250 | + xt_strcat(PATH_MAX, path, ref_table); |
251 | + } |
252 | |
253 | fk->fk_ref_tab_name = (XTPathStrPtr) xt_dup_string(self, path); |
254 | } |
255 | @@ -2065,8 +2078,13 @@ |
256 | |
257 | void XTDDForeignKey::loadString(XTThreadPtr self, XTStringBufferPtr sb) |
258 | { |
259 | + char schema_name[XT_IDENTIFIER_NAME_SIZE]; |
260 | + |
261 | XTDDConstraint::loadString(self, sb); |
262 | xt_sb_concat(self, sb, " REFERENCES `"); |
263 | + xt_2nd_last_name_of_path(XT_IDENTIFIER_NAME_SIZE, schema_name, fk_ref_tab_name->ps_path); |
264 | + xt_sb_concat(self, sb, schema_name); |
265 | + xt_sb_concat(self, sb, "`.`"); |
266 | xt_sb_concat(self, sb, xt_last_name_of_path(fk_ref_tab_name->ps_path)); |
267 | xt_sb_concat(self, sb, "` "); |
268 | |
269 | @@ -2877,9 +2895,33 @@ |
270 | return ok; |
271 | } |
272 | |
273 | -xtBool XTDDTable::checkCanDrop() |
274 | +/* |
275 | + * drop_db parameter is TRUE if we are dropping the schema of this table. In this case |
276 | + * we return TRUE if the table has only refs to the tables from its own schema |
277 | + */ |
278 | +xtBool XTDDTable::checkCanDrop(xtBool drop_db) |
279 | { |
280 | /* no refs or references only itself */ |
281 | - return (dt_trefs == NULL) || |
282 | - ((dt_trefs->tr_next == NULL) && (dt_trefs->tr_fkey->co_table == this)); |
283 | + if ((dt_trefs == NULL) || ((dt_trefs->tr_next == NULL) && (dt_trefs->tr_fkey->co_table == this))) |
284 | + return TRUE; |
285 | + |
286 | + if (!drop_db) |
287 | + return FALSE; |
288 | + |
289 | + const char *this_schema = xt_last_2_names_of_path(dt_table->tab_name->ps_path); |
290 | + size_t this_schema_sz = xt_last_name_of_path(dt_table->tab_name->ps_path) - this_schema; |
291 | + XTDDTableRef *tr = dt_trefs; |
292 | + |
293 | + while (tr) { |
294 | + const char *tab_path = tr->tr_fkey->co_table->dt_table->tab_name->ps_path; |
295 | + const char *tab_schema = xt_last_2_names_of_path(tab_path); |
296 | + size_t tab_schema_sz = xt_last_name_of_path(tab_path) - tab_schema; |
297 | + |
298 | + if (this_schema_sz != tab_schema_sz || strncmp(this_schema, tab_schema, tab_schema_sz)) |
299 | + return FALSE; |
300 | + |
301 | + tr = tr->tr_next; |
302 | + } |
303 | + |
304 | + return TRUE; |
305 | } |
306 | |
307 | === modified file 'src/datadic_xt.h' |
308 | --- src/datadic_xt.h 2009-05-19 15:22:26 +0000 |
309 | +++ src/datadic_xt.h 2009-06-12 14:29:30 +0000 |
310 | @@ -288,7 +288,7 @@ |
311 | XTDDIndex *findReferenceIndex(XTDDForeignKey *fk); |
312 | bool insertRow(struct XTOpenTable *rec_ot, xtWord1 *buffer); |
313 | bool checkNoAction(struct XTOpenTable *ot, xtRecordID rec_id); |
314 | - xtBool checkCanDrop(); |
315 | + xtBool checkCanDrop(xtBool drop_db); |
316 | bool deleteRow(struct XTOpenTable *rec_ot, xtWord1 *buffer); |
317 | void deleteAllRows(XTThreadPtr self); |
318 | bool updateRow(struct XTOpenTable *rec_ot, xtWord1 *before, xtWord1 *after); |
319 | |
320 | === modified file 'src/ha_pbxt.cc' |
321 | --- src/ha_pbxt.cc 2009-06-10 16:26:33 +0000 |
322 | +++ src/ha_pbxt.cc 2009-06-12 14:29:30 +0000 |
323 | @@ -4682,7 +4682,7 @@ |
324 | pushr_(ha_release_exclusive_use, share); |
325 | ha_close_open_tables(self, share, NULL); |
326 | |
327 | - xt_drop_table(self, (XTPathStrPtr) table_path); |
328 | + xt_drop_table(self, (XTPathStrPtr) table_path, thd_sql_command(thd) == SQLCOM_DROP_DB); |
329 | |
330 | freer_(); // ha_release_exclusive_use(share) |
331 | freer_(); // ha_unget_share(share) |
332 | |
333 | === modified file 'src/table_xt.cc' |
334 | --- src/table_xt.cc 2009-05-26 14:01:46 +0000 |
335 | +++ src/table_xt.cc 2009-06-12 14:29:30 +0000 |
336 | @@ -1590,7 +1590,7 @@ |
337 | exit_(); |
338 | } |
339 | |
340 | -xtPublic void xt_drop_table(XTThreadPtr self, XTPathStrPtr tab_name) |
341 | +xtPublic void xt_drop_table(XTThreadPtr self, XTPathStrPtr tab_name, xtBool drop_db) |
342 | { |
343 | XTDatabaseHPtr db = self->st_database; |
344 | XTOpenTablePoolPtr table_pool; |
345 | @@ -1614,7 +1614,7 @@ |
346 | tab_id = tab->tab_id; /* tab is not null if returned table_pool is not null */ |
347 | /* check if other tables refer this */ |
348 | if (!self->st_ignore_fkeys) |
349 | - can_drop = tab->tab_dic.dic_table->checkCanDrop(); |
350 | + can_drop = tab->tab_dic.dic_table->checkCanDrop(drop_db); |
351 | } |
352 | #ifdef DRIZZLED |
353 | /* See the comment in ha_pbxt::delete_table regarding different implmentation of DROP TABLE |
354 | |
355 | === modified file 'src/table_xt.h' |
356 | --- src/table_xt.h 2009-05-28 15:17:16 +0000 |
357 | +++ src/table_xt.h 2009-06-12 14:29:30 +0000 |
358 | @@ -514,7 +514,7 @@ |
359 | int xt_use_table_by_id(struct XTThread *self, XTTableHPtr *tab, struct XTDatabase *db, xtTableID tab_id); |
360 | XTOpenTablePtr xt_open_table(XTTableHPtr tab); |
361 | void xt_close_table(XTOpenTablePtr ot, xtBool flush, xtBool have_table_lock); |
362 | -void xt_drop_table(struct XTThread *self, XTPathStrPtr name); |
363 | +void xt_drop_table(struct XTThread *self, XTPathStrPtr name, xtBool drop_db); |
364 | void xt_check_table(XTThreadPtr self, XTOpenTablePtr tab); |
365 | void xt_rename_table(struct XTThread *self, XTPathStrPtr old_name, XTPathStrPtr new_name); |
366 | |
367 | |
368 | === modified file 'test/mysql-test/r/pbxt_bugs.result' |
369 | --- test/mysql-test/r/pbxt_bugs.result 2009-06-10 16:26:33 +0000 |
370 | +++ test/mysql-test/r/pbxt_bugs.result 2009-06-12 14:29:30 +0000 |
371 | @@ -1230,3 +1230,25 @@ |
372 | 3 |
373 | 4 |
374 | drop table child, parent; |
375 | +create schema test378222; |
376 | +use test378222; |
377 | +create table t1 (id int primary key); |
378 | +create table t2 (id int primary key); |
379 | +alter table t1 add constraint foreign key (id) references t2 (id); |
380 | +alter table t2 add constraint foreign key (id) references t1 (id); |
381 | +drop schema test378222; |
382 | +create schema test378222a; |
383 | +create schema test378222b; |
384 | +create table test378222a.t1 (id int primary key) engine = pbxt; |
385 | +create table test378222b.t2 (id int primary key) engine = pbxt; |
386 | +alter table test378222a.t1 add constraint foreign key (id) references test378222b.t2 (id); |
387 | +alter table test378222b.t2 add constraint foreign key (id) references test378222a.t1 (id); |
388 | +set foreign_key_checks = 1; |
389 | +drop schema test378222a; |
390 | +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails |
391 | +drop schema test378222b; |
392 | +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails |
393 | +set foreign_key_checks = 0; |
394 | +drop schema test378222a; |
395 | +drop schema test378222b; |
396 | +set foreign_key_checks = 1; |
397 | |
398 | === modified file 'test/mysql-test/t/pbxt_bugs.test' |
399 | --- test/mysql-test/t/pbxt_bugs.test 2009-06-10 16:26:33 +0000 |
400 | +++ test/mysql-test/t/pbxt_bugs.test 2009-06-12 14:29:30 +0000 |
401 | @@ -938,7 +938,34 @@ |
402 | |
403 | drop table child, parent; |
404 | |
405 | +# bug 378222: Drop sakila causes error: Cannot delete or update a parent row: a foreign key constraint fails |
406 | + |
407 | +create schema test378222; |
408 | +use test378222; |
409 | +create table t1 (id int primary key); |
410 | +create table t2 (id int primary key); |
411 | +alter table t1 add constraint foreign key (id) references t2 (id); |
412 | +alter table t2 add constraint foreign key (id) references t1 (id); |
413 | +drop schema test378222; |
414 | + |
415 | +create schema test378222a; |
416 | +create schema test378222b; |
417 | +create table test378222a.t1 (id int primary key) engine = pbxt; |
418 | +create table test378222b.t2 (id int primary key) engine = pbxt; |
419 | +alter table test378222a.t1 add constraint foreign key (id) references test378222b.t2 (id); |
420 | +alter table test378222b.t2 add constraint foreign key (id) references test378222a.t1 (id); |
421 | +set foreign_key_checks = 1; |
422 | +--error 1217 |
423 | +drop schema test378222a; |
424 | +--error 1217 |
425 | +drop schema test378222b; |
426 | +set foreign_key_checks = 0; |
427 | +drop schema test378222a; |
428 | +drop schema test378222b; |
429 | +set foreign_key_checks = 1; |
430 | + |
431 | --disable_query_log |
432 | +use test; |
433 | DROP TABLE t2, t5; |
434 | drop database pbxt; |
435 | --enable_query_log |
Hi Vlad,
This patch looks good. Just one thing: how about doing this in
xt_tab_init_db()?
I think this would be more efficient.
On Jun 12, 2009, at 4:40 PM, Vladimir Kolesnikov wrote:
> === modified file 'src/database_ xt.cc' database( XTThreadPtr self, char *path, xtBool database( self, path, multi_path); xt_heap_ release, db); database( self, db, XT_FOR_USER); release( self, db); tables_ init(self, db, &desc); xt_describe_ tables_ exit, &desc); tables_ next(self, &desc)) { tab_path- >tp_path) ; dir_char( PATH_MAX, table_path. ps_path) ; release( self, xt_use_table(self, &table_path, FALSE, tables_ exit(self, desc); release( self, db);
> --- src/database_xt.cc 2009-05-28 15:17:16 +0000
> +++ src/database_xt.cc 2009-06-12 14:29:30 +0000
> @@ -616,7 +616,9 @@
> xtPublic void xt_open_
> multi_path)
> {
> XTDatabaseHPtr db;
> -
> + XTTableDescRec desc;
> + XTPathStr table_path;
> +
> /* We cannot get a database, without unusing the current
> * first. The reason is that the restart process will
> * partially set the current database!
> @@ -625,7 +627,18 @@
> db = xt_get_
> pushr_(
> xt_use_
> - freer_(); // xt_heap_
> +
> + xt_describe_
> + pushr_(
> + while (xt_describe_
> + xt_strcpy(PATH_MAX, table_path.ps_path, desc.td_
> + xt_add_
> + xt_strcat(PATH_MAX, table_path.ps_path, desc.td_tab_name);
> + xt_heap_
> FALSE, NULL));
> + }
> +
> + freer_(); // xt_describe_
> + freer_(); // xt_heap_
> }
>
-- ng.org
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreami
pbxt.blogspot.com