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 | 3 | 3 | ||
6 | 4 | ------- 1.0.08 RC - Not yet released | 4 | ------- 1.0.08 RC - Not yet released |
7 | 5 | 5 | ||
8 | 6 | RN246: Fixed bug #378222: Drop sakila causes error: Cannot delete or update a parent row: a foreign key constraint fails | ||
9 | 7 | |||
10 | 6 | RN245: Fixed bug #379315: Inconsistent behavior of DELETE IGNORE and FK constraint | 8 | RN245: Fixed bug #379315: Inconsistent behavior of DELETE IGNORE and FK constraint |
11 | 7 | 9 | ||
12 | 8 | 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 | 10 | 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 | 9 | 11 | ||
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 | 616 | xtPublic void xt_open_database(XTThreadPtr self, char *path, xtBool multi_path) | 616 | xtPublic void xt_open_database(XTThreadPtr self, char *path, xtBool multi_path) |
19 | 617 | { | 617 | { |
20 | 618 | XTDatabaseHPtr db; | 618 | XTDatabaseHPtr db; |
22 | 619 | 619 | XTTableDescRec desc; | |
23 | 620 | XTPathStr table_path; | ||
24 | 621 | |||
25 | 620 | /* We cannot get a database, without unusing the current | 622 | /* We cannot get a database, without unusing the current |
26 | 621 | * first. The reason is that the restart process will | 623 | * first. The reason is that the restart process will |
27 | 622 | * partially set the current database! | 624 | * partially set the current database! |
28 | @@ -625,7 +627,18 @@ | |||
29 | 625 | db = xt_get_database(self, path, multi_path); | 627 | db = xt_get_database(self, path, multi_path); |
30 | 626 | pushr_(xt_heap_release, db); | 628 | pushr_(xt_heap_release, db); |
31 | 627 | xt_use_database(self, db, XT_FOR_USER); | 629 | xt_use_database(self, db, XT_FOR_USER); |
33 | 628 | freer_(); // xt_heap_release(self, db); | 630 | |
34 | 631 | xt_describe_tables_init(self, db, &desc); | ||
35 | 632 | pushr_(xt_describe_tables_exit, &desc); | ||
36 | 633 | while (xt_describe_tables_next(self, &desc)) { | ||
37 | 634 | xt_strcpy(PATH_MAX, table_path.ps_path, desc.td_tab_path->tp_path); | ||
38 | 635 | xt_add_dir_char(PATH_MAX, table_path.ps_path); | ||
39 | 636 | xt_strcat(PATH_MAX, table_path.ps_path, desc.td_tab_name); | ||
40 | 637 | xt_heap_release(self, xt_use_table(self, &table_path, FALSE, FALSE, NULL)); | ||
41 | 638 | } | ||
42 | 639 | |||
43 | 640 | freer_(); // xt_describe_tables_exit(self, desc); | ||
44 | 641 | freer_(); // xt_heap_release(self, db); | ||
45 | 629 | } | 642 | } |
46 | 630 | 643 | ||
47 | 631 | /* This function can only be called if you do not already have a database in | 644 | /* This function can only be called if you do not already have a database in |
48 | 632 | 645 | ||
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 | 650 | int parseKeyAction(XTThreadPtr self); | 650 | int parseKeyAction(XTThreadPtr self); |
54 | 651 | void parseCreateTable(XTThreadPtr self); | 651 | void parseCreateTable(XTThreadPtr self); |
55 | 652 | void parseAddTableItem(XTThreadPtr self); | 652 | void parseAddTableItem(XTThreadPtr self); |
57 | 653 | void parseQualifiedName(XTThreadPtr self, char *name); | 653 | void parseQualifiedName(XTThreadPtr self, char *parent_name, char *name); |
58 | 654 | void parseTableName(XTThreadPtr self, bool alterTable); | 654 | void parseTableName(XTThreadPtr self, bool alterTable); |
59 | 655 | void parseExpression(XTThreadPtr self, bool allow_reserved); | 655 | void parseExpression(XTThreadPtr self, bool allow_reserved); |
60 | 656 | void parseBrackets(XTThreadPtr self); | 656 | void parseBrackets(XTThreadPtr self); |
61 | @@ -720,7 +720,7 @@ | |||
62 | 720 | } | 720 | } |
63 | 721 | virtual void addListedColumn(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(index_col_name)) { | 721 | virtual void addListedColumn(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(index_col_name)) { |
64 | 722 | } | 722 | } |
66 | 723 | virtual void setReferencedTable(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(ref_table)) { | 723 | virtual void setReferencedTable(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(ref_schema), char *XT_UNUSED(ref_table)) { |
67 | 724 | } | 724 | } |
68 | 725 | virtual void addReferencedColumn(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(index_col_name)) { | 725 | virtual void addReferencedColumn(XTThreadPtr XT_UNUSED(self), char *XT_UNUSED(index_col_name)) { |
69 | 726 | } | 726 | } |
70 | @@ -870,7 +870,7 @@ | |||
71 | 870 | if (pt_current->isKeyWord("CONSTRAINT")) { | 870 | if (pt_current->isKeyWord("CONSTRAINT")) { |
72 | 871 | pt_current = pt_tokenizer->nextToken(self); | 871 | pt_current = pt_tokenizer->nextToken(self); |
73 | 872 | if (pt_current->isIdentifier()) | 872 | if (pt_current->isIdentifier()) |
75 | 873 | parseQualifiedName(self, name); | 873 | parseQualifiedName(self, NULL, name); |
76 | 874 | } | 874 | } |
77 | 875 | 875 | ||
78 | 876 | if (pt_current->isReservedWord(XT_TK_PRIMARY)) { | 876 | if (pt_current->isReservedWord(XT_TK_PRIMARY)) { |
79 | @@ -985,13 +985,15 @@ | |||
80 | 985 | char name[XT_IDENTIFIER_NAME_SIZE]; | 985 | char name[XT_IDENTIFIER_NAME_SIZE]; |
81 | 986 | 986 | ||
82 | 987 | pt_current = pt_tokenizer->nextToken(self); | 987 | pt_current = pt_tokenizer->nextToken(self); |
84 | 988 | parseQualifiedName(self, name); | 988 | parseQualifiedName(self, NULL, name); |
85 | 989 | moveColumn(self, name); | 989 | moveColumn(self, name); |
86 | 990 | } | 990 | } |
87 | 991 | } | 991 | } |
88 | 992 | 992 | ||
90 | 993 | void XTParseTable::parseQualifiedName(XTThreadPtr self, char *name) | 993 | void XTParseTable::parseQualifiedName(XTThreadPtr self, char *parent_name, char *name) |
91 | 994 | { | 994 | { |
92 | 995 | if (parent_name) | ||
93 | 996 | parent_name[0] = '\0'; | ||
94 | 995 | /* Should be an identifier by I have this example: | 997 | /* Should be an identifier by I have this example: |
95 | 996 | * CREATE TABLE t1 ( comment CHAR(32) ASCII NOT NULL, koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL default '' ) CHARSET=latin5; | 998 | * CREATE TABLE t1 ( comment CHAR(32) ASCII NOT NULL, koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL default '' ) CHARSET=latin5; |
96 | 997 | * | 999 | * |
97 | @@ -1001,6 +1003,8 @@ | |||
98 | 1001 | raiseError(self, pt_current, XT_ERR_ID_TOO_LONG); | 1003 | raiseError(self, pt_current, XT_ERR_ID_TOO_LONG); |
99 | 1002 | pt_current = pt_tokenizer->nextToken(self); | 1004 | pt_current = pt_tokenizer->nextToken(self); |
100 | 1003 | while (pt_current->isKeyWord(".")) { | 1005 | while (pt_current->isKeyWord(".")) { |
101 | 1006 | if (parent_name) | ||
102 | 1007 | xt_strcpy(XT_IDENTIFIER_NAME_SIZE,parent_name, name); | ||
103 | 1004 | pt_current = pt_tokenizer->nextToken(self); | 1008 | pt_current = pt_tokenizer->nextToken(self); |
104 | 1005 | /* Accept anything after the DOT! */ | 1009 | /* Accept anything after the DOT! */ |
105 | 1006 | if (pt_current->getString(name, XT_IDENTIFIER_NAME_SIZE) >= XT_IDENTIFIER_NAME_SIZE) | 1010 | if (pt_current->getString(name, XT_IDENTIFIER_NAME_SIZE) >= XT_IDENTIFIER_NAME_SIZE) |
106 | @@ -1013,7 +1017,7 @@ | |||
107 | 1013 | { | 1017 | { |
108 | 1014 | char name[XT_IDENTIFIER_NAME_SIZE]; | 1018 | char name[XT_IDENTIFIER_NAME_SIZE]; |
109 | 1015 | 1019 | ||
111 | 1016 | parseQualifiedName(self, name); | 1020 | parseQualifiedName(self, NULL, name); |
112 | 1017 | setTableName(self, name, alterTable); | 1021 | setTableName(self, name, alterTable); |
113 | 1018 | } | 1022 | } |
114 | 1019 | 1023 | ||
115 | @@ -1022,7 +1026,7 @@ | |||
116 | 1022 | char col_name[XT_IDENTIFIER_NAME_SIZE]; | 1026 | char col_name[XT_IDENTIFIER_NAME_SIZE]; |
117 | 1023 | 1027 | ||
118 | 1024 | // column_definition | 1028 | // column_definition |
120 | 1025 | parseQualifiedName(self, col_name); | 1029 | parseQualifiedName(self, NULL, col_name); |
121 | 1026 | addColumn(self, col_name, old_col_name); | 1030 | addColumn(self, col_name, old_col_name); |
122 | 1027 | parseDataType(self); | 1031 | parseDataType(self); |
123 | 1028 | 1032 | ||
124 | @@ -1122,7 +1126,7 @@ | |||
125 | 1122 | pt_current->expectKeyWord(self, "("); | 1126 | pt_current->expectKeyWord(self, "("); |
126 | 1123 | do { | 1127 | do { |
127 | 1124 | pt_current = pt_tokenizer->nextToken(self); | 1128 | pt_current = pt_tokenizer->nextToken(self); |
129 | 1125 | parseQualifiedName(self, name); | 1129 | parseQualifiedName(self, NULL, name); |
130 | 1126 | addListedColumn(self, name); | 1130 | addListedColumn(self, name); |
131 | 1127 | cols++; | 1131 | cols++; |
132 | 1128 | if (index_cols) { | 1132 | if (index_cols) { |
133 | @@ -1146,19 +1150,20 @@ | |||
134 | 1146 | int on_delete = XT_KEY_ACTION_DEFAULT; | 1150 | int on_delete = XT_KEY_ACTION_DEFAULT; |
135 | 1147 | int on_update = XT_KEY_ACTION_DEFAULT; | 1151 | int on_update = XT_KEY_ACTION_DEFAULT; |
136 | 1148 | char name[XT_IDENTIFIER_NAME_SIZE]; | 1152 | char name[XT_IDENTIFIER_NAME_SIZE]; |
137 | 1153 | char parent_name[XT_IDENTIFIER_NAME_SIZE]; | ||
138 | 1149 | u_int cols = 0; | 1154 | u_int cols = 0; |
139 | 1150 | 1155 | ||
140 | 1151 | // REFERENCES tbl_name | 1156 | // REFERENCES tbl_name |
141 | 1152 | pt_current = pt_tokenizer->nextToken(self, "REFERENCES", pt_current); | 1157 | pt_current = pt_tokenizer->nextToken(self, "REFERENCES", pt_current); |
144 | 1153 | parseQualifiedName(self, name); | 1158 | parseQualifiedName(self, parent_name, name); |
145 | 1154 | setReferencedTable(self, name); | 1159 | setReferencedTable(self, parent_name[0] ? parent_name : NULL, name); |
146 | 1155 | 1160 | ||
147 | 1156 | // [ (index_col_name,...) ] | 1161 | // [ (index_col_name,...) ] |
148 | 1157 | if (pt_current->isKeyWord("(")) { | 1162 | if (pt_current->isKeyWord("(")) { |
149 | 1158 | pt_current->expectKeyWord(self, "("); | 1163 | pt_current->expectKeyWord(self, "("); |
150 | 1159 | do { | 1164 | do { |
151 | 1160 | pt_current = pt_tokenizer->nextToken(self); | 1165 | pt_current = pt_tokenizer->nextToken(self); |
153 | 1161 | parseQualifiedName(self, name); | 1166 | parseQualifiedName(self, NULL, name); |
154 | 1162 | addReferencedColumn(self, name); | 1167 | addReferencedColumn(self, name); |
155 | 1163 | cols++; | 1168 | cols++; |
156 | 1164 | if (cols > req_cols) | 1169 | if (cols > req_cols) |
157 | @@ -1230,7 +1235,7 @@ | |||
158 | 1230 | if (pt_current->isReservedWord(XT_TK_COLUMN)) | 1235 | if (pt_current->isReservedWord(XT_TK_COLUMN)) |
159 | 1231 | pt_current = pt_tokenizer->nextToken(self); | 1236 | pt_current = pt_tokenizer->nextToken(self); |
160 | 1232 | 1237 | ||
162 | 1233 | parseQualifiedName(self, old_col_name); | 1238 | parseQualifiedName(self, NULL, old_col_name); |
163 | 1234 | parseColumnDefinition(self, old_col_name); | 1239 | parseColumnDefinition(self, old_col_name); |
164 | 1235 | parseMoveColumn(self); | 1240 | parseMoveColumn(self); |
165 | 1236 | } | 1241 | } |
166 | @@ -1262,7 +1267,7 @@ | |||
167 | 1262 | else { | 1267 | else { |
168 | 1263 | if (pt_current->isReservedWord(XT_TK_COLUMN)) | 1268 | if (pt_current->isReservedWord(XT_TK_COLUMN)) |
169 | 1264 | pt_current = pt_tokenizer->nextToken(self); | 1269 | pt_current = pt_tokenizer->nextToken(self); |
171 | 1265 | parseQualifiedName(self, name); | 1270 | parseQualifiedName(self, NULL, name); |
172 | 1266 | dropColumn(self, name); | 1271 | dropColumn(self, name); |
173 | 1267 | } | 1272 | } |
174 | 1268 | } | 1273 | } |
175 | @@ -1270,7 +1275,7 @@ | |||
176 | 1270 | pt_current = pt_tokenizer->nextToken(self); | 1275 | pt_current = pt_tokenizer->nextToken(self); |
177 | 1271 | if (pt_current->isKeyWord("TO")) | 1276 | if (pt_current->isKeyWord("TO")) |
178 | 1272 | pt_current = pt_tokenizer->nextToken(self); | 1277 | pt_current = pt_tokenizer->nextToken(self); |
180 | 1273 | parseQualifiedName(self, name); | 1278 | parseQualifiedName(self, NULL, name); |
181 | 1274 | } | 1279 | } |
182 | 1275 | else | 1280 | else |
183 | 1276 | /* Just ignore the syntax until the next , */ | 1281 | /* Just ignore the syntax until the next , */ |
184 | @@ -1295,7 +1300,7 @@ | |||
185 | 1295 | else if (pt_current->isKeyWord("SPACIAL")) | 1300 | else if (pt_current->isKeyWord("SPACIAL")) |
186 | 1296 | pt_current = pt_tokenizer->nextToken(self); | 1301 | pt_current = pt_tokenizer->nextToken(self); |
187 | 1297 | pt_current = pt_tokenizer->nextToken(self, "INDEX", pt_current); | 1302 | pt_current = pt_tokenizer->nextToken(self, "INDEX", pt_current); |
189 | 1298 | parseQualifiedName(self, name); | 1303 | parseQualifiedName(self, NULL, name); |
190 | 1299 | optionalIndexType(self); | 1304 | optionalIndexType(self); |
191 | 1300 | pt_current = pt_tokenizer->nextToken(self, "ON", pt_current); | 1305 | pt_current = pt_tokenizer->nextToken(self, "ON", pt_current); |
192 | 1301 | parseTableName(self, true); | 1306 | parseTableName(self, true); |
193 | @@ -1310,7 +1315,7 @@ | |||
194 | 1310 | 1315 | ||
195 | 1311 | pt_current = pt_tokenizer->nextToken(self, "DROP", pt_current); | 1316 | pt_current = pt_tokenizer->nextToken(self, "DROP", pt_current); |
196 | 1312 | pt_current = pt_tokenizer->nextToken(self, "INDEX", pt_current); | 1317 | pt_current = pt_tokenizer->nextToken(self, "INDEX", pt_current); |
198 | 1313 | parseQualifiedName(self, name); | 1318 | parseQualifiedName(self, NULL, name); |
199 | 1314 | pt_current = pt_tokenizer->nextToken(self, "ON", pt_current); | 1319 | pt_current = pt_tokenizer->nextToken(self, "ON", pt_current); |
200 | 1315 | parseTableName(self, true); | 1320 | parseTableName(self, true); |
201 | 1316 | dropConstraint(self, name, XT_DD_INDEX); | 1321 | dropConstraint(self, name, XT_DD_INDEX); |
202 | @@ -1351,7 +1356,7 @@ | |||
203 | 1351 | virtual void addConstraint(XTThreadPtr self, char *name, u_int type, bool lastColumn); | 1356 | virtual void addConstraint(XTThreadPtr self, char *name, u_int type, bool lastColumn); |
204 | 1352 | virtual void dropConstraint(XTThreadPtr self, char *name, u_int type); | 1357 | virtual void dropConstraint(XTThreadPtr self, char *name, u_int type); |
205 | 1353 | virtual void addListedColumn(XTThreadPtr self, char *index_col_name); | 1358 | virtual void addListedColumn(XTThreadPtr self, char *index_col_name); |
207 | 1354 | virtual void setReferencedTable(XTThreadPtr self, char *ref_table); | 1359 | virtual void setReferencedTable(XTThreadPtr self, char *ref_schema, char *ref_table); |
208 | 1355 | virtual void addReferencedColumn(XTThreadPtr self, char *index_col_name); | 1360 | virtual void addReferencedColumn(XTThreadPtr self, char *index_col_name); |
209 | 1356 | virtual void setActions(XTThreadPtr self, int on_delete, int on_update); | 1361 | virtual void setActions(XTThreadPtr self, int on_delete, int on_update); |
210 | 1357 | 1362 | ||
211 | @@ -1546,23 +1551,31 @@ | |||
212 | 1546 | } | 1551 | } |
213 | 1547 | } | 1552 | } |
214 | 1548 | 1553 | ||
216 | 1549 | void XTCreateTable::setReferencedTable(XTThreadPtr self, char *ref_table) | 1554 | void XTCreateTable::setReferencedTable(XTThreadPtr self, char *ref_schema, char *ref_table) |
217 | 1550 | { | 1555 | { |
218 | 1551 | XTDDForeignKey *fk = (XTDDForeignKey *) ct_curr_constraint; | 1556 | XTDDForeignKey *fk = (XTDDForeignKey *) ct_curr_constraint; |
219 | 1552 | char path[PATH_MAX]; | 1557 | char path[PATH_MAX]; |
220 | 1553 | 1558 | ||
232 | 1554 | xt_strcpy(PATH_MAX, path, ct_tab_path->ps_path); | 1559 | if (ref_schema) { |
233 | 1555 | xt_remove_last_name_of_path(path); | 1560 | xt_strcpy(PATH_MAX,path, "."); |
234 | 1556 | if (ct_convert) { | 1561 | xt_add_dir_char(PATH_MAX, path); |
235 | 1557 | char buffer[XT_IDENTIFIER_NAME_SIZE]; | 1562 | xt_strcat(PATH_MAX, path, ref_schema); |
236 | 1558 | size_t len; | 1563 | xt_add_dir_char(PATH_MAX, path); |
226 | 1559 | |||
227 | 1560 | myxt_static_convert_identifier(self, ct_charset, ref_table, buffer, XT_IDENTIFIER_NAME_SIZE); | ||
228 | 1561 | len = strlen(path); | ||
229 | 1562 | myxt_static_convert_table_name(self, buffer, &path[len], PATH_MAX - len); | ||
230 | 1563 | } | ||
231 | 1564 | else | ||
237 | 1565 | xt_strcat(PATH_MAX, path, ref_table); | 1564 | xt_strcat(PATH_MAX, path, ref_table); |
238 | 1565 | } else { | ||
239 | 1566 | xt_strcpy(PATH_MAX, path, ct_tab_path->ps_path); | ||
240 | 1567 | xt_remove_last_name_of_path(path); | ||
241 | 1568 | if (ct_convert) { | ||
242 | 1569 | char buffer[XT_IDENTIFIER_NAME_SIZE]; | ||
243 | 1570 | size_t len; | ||
244 | 1571 | |||
245 | 1572 | myxt_static_convert_identifier(self, ct_charset, ref_table, buffer, XT_IDENTIFIER_NAME_SIZE); | ||
246 | 1573 | len = strlen(path); | ||
247 | 1574 | myxt_static_convert_table_name(self, buffer, &path[len], PATH_MAX - len); | ||
248 | 1575 | } | ||
249 | 1576 | else | ||
250 | 1577 | xt_strcat(PATH_MAX, path, ref_table); | ||
251 | 1578 | } | ||
252 | 1566 | 1579 | ||
253 | 1567 | fk->fk_ref_tab_name = (XTPathStrPtr) xt_dup_string(self, path); | 1580 | fk->fk_ref_tab_name = (XTPathStrPtr) xt_dup_string(self, path); |
254 | 1568 | } | 1581 | } |
255 | @@ -2065,8 +2078,13 @@ | |||
256 | 2065 | 2078 | ||
257 | 2066 | void XTDDForeignKey::loadString(XTThreadPtr self, XTStringBufferPtr sb) | 2079 | void XTDDForeignKey::loadString(XTThreadPtr self, XTStringBufferPtr sb) |
258 | 2067 | { | 2080 | { |
259 | 2081 | char schema_name[XT_IDENTIFIER_NAME_SIZE]; | ||
260 | 2082 | |||
261 | 2068 | XTDDConstraint::loadString(self, sb); | 2083 | XTDDConstraint::loadString(self, sb); |
262 | 2069 | xt_sb_concat(self, sb, " REFERENCES `"); | 2084 | xt_sb_concat(self, sb, " REFERENCES `"); |
263 | 2085 | xt_2nd_last_name_of_path(XT_IDENTIFIER_NAME_SIZE, schema_name, fk_ref_tab_name->ps_path); | ||
264 | 2086 | xt_sb_concat(self, sb, schema_name); | ||
265 | 2087 | xt_sb_concat(self, sb, "`.`"); | ||
266 | 2070 | xt_sb_concat(self, sb, xt_last_name_of_path(fk_ref_tab_name->ps_path)); | 2088 | xt_sb_concat(self, sb, xt_last_name_of_path(fk_ref_tab_name->ps_path)); |
267 | 2071 | xt_sb_concat(self, sb, "` "); | 2089 | xt_sb_concat(self, sb, "` "); |
268 | 2072 | 2090 | ||
269 | @@ -2877,9 +2895,33 @@ | |||
270 | 2877 | return ok; | 2895 | return ok; |
271 | 2878 | } | 2896 | } |
272 | 2879 | 2897 | ||
274 | 2880 | xtBool XTDDTable::checkCanDrop() | 2898 | /* |
275 | 2899 | * drop_db parameter is TRUE if we are dropping the schema of this table. In this case | ||
276 | 2900 | * we return TRUE if the table has only refs to the tables from its own schema | ||
277 | 2901 | */ | ||
278 | 2902 | xtBool XTDDTable::checkCanDrop(xtBool drop_db) | ||
279 | 2881 | { | 2903 | { |
280 | 2882 | /* no refs or references only itself */ | 2904 | /* no refs or references only itself */ |
283 | 2883 | return (dt_trefs == NULL) || | 2905 | if ((dt_trefs == NULL) || ((dt_trefs->tr_next == NULL) && (dt_trefs->tr_fkey->co_table == this))) |
284 | 2884 | ((dt_trefs->tr_next == NULL) && (dt_trefs->tr_fkey->co_table == this)); | 2906 | return TRUE; |
285 | 2907 | |||
286 | 2908 | if (!drop_db) | ||
287 | 2909 | return FALSE; | ||
288 | 2910 | |||
289 | 2911 | const char *this_schema = xt_last_2_names_of_path(dt_table->tab_name->ps_path); | ||
290 | 2912 | size_t this_schema_sz = xt_last_name_of_path(dt_table->tab_name->ps_path) - this_schema; | ||
291 | 2913 | XTDDTableRef *tr = dt_trefs; | ||
292 | 2914 | |||
293 | 2915 | while (tr) { | ||
294 | 2916 | const char *tab_path = tr->tr_fkey->co_table->dt_table->tab_name->ps_path; | ||
295 | 2917 | const char *tab_schema = xt_last_2_names_of_path(tab_path); | ||
296 | 2918 | size_t tab_schema_sz = xt_last_name_of_path(tab_path) - tab_schema; | ||
297 | 2919 | |||
298 | 2920 | if (this_schema_sz != tab_schema_sz || strncmp(this_schema, tab_schema, tab_schema_sz)) | ||
299 | 2921 | return FALSE; | ||
300 | 2922 | |||
301 | 2923 | tr = tr->tr_next; | ||
302 | 2924 | } | ||
303 | 2925 | |||
304 | 2926 | return TRUE; | ||
305 | 2885 | } | 2927 | } |
306 | 2886 | 2928 | ||
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 | 288 | XTDDIndex *findReferenceIndex(XTDDForeignKey *fk); | 288 | XTDDIndex *findReferenceIndex(XTDDForeignKey *fk); |
312 | 289 | bool insertRow(struct XTOpenTable *rec_ot, xtWord1 *buffer); | 289 | bool insertRow(struct XTOpenTable *rec_ot, xtWord1 *buffer); |
313 | 290 | bool checkNoAction(struct XTOpenTable *ot, xtRecordID rec_id); | 290 | bool checkNoAction(struct XTOpenTable *ot, xtRecordID rec_id); |
315 | 291 | xtBool checkCanDrop(); | 291 | xtBool checkCanDrop(xtBool drop_db); |
316 | 292 | bool deleteRow(struct XTOpenTable *rec_ot, xtWord1 *buffer); | 292 | bool deleteRow(struct XTOpenTable *rec_ot, xtWord1 *buffer); |
317 | 293 | void deleteAllRows(XTThreadPtr self); | 293 | void deleteAllRows(XTThreadPtr self); |
318 | 294 | bool updateRow(struct XTOpenTable *rec_ot, xtWord1 *before, xtWord1 *after); | 294 | bool updateRow(struct XTOpenTable *rec_ot, xtWord1 *before, xtWord1 *after); |
319 | 295 | 295 | ||
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 | 4682 | pushr_(ha_release_exclusive_use, share); | 4682 | pushr_(ha_release_exclusive_use, share); |
325 | 4683 | ha_close_open_tables(self, share, NULL); | 4683 | ha_close_open_tables(self, share, NULL); |
326 | 4684 | 4684 | ||
328 | 4685 | xt_drop_table(self, (XTPathStrPtr) table_path); | 4685 | xt_drop_table(self, (XTPathStrPtr) table_path, thd_sql_command(thd) == SQLCOM_DROP_DB); |
329 | 4686 | 4686 | ||
330 | 4687 | freer_(); // ha_release_exclusive_use(share) | 4687 | freer_(); // ha_release_exclusive_use(share) |
331 | 4688 | freer_(); // ha_unget_share(share) | 4688 | freer_(); // ha_unget_share(share) |
332 | 4689 | 4689 | ||
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 | 1590 | exit_(); | 1590 | exit_(); |
338 | 1591 | } | 1591 | } |
339 | 1592 | 1592 | ||
341 | 1593 | xtPublic void xt_drop_table(XTThreadPtr self, XTPathStrPtr tab_name) | 1593 | xtPublic void xt_drop_table(XTThreadPtr self, XTPathStrPtr tab_name, xtBool drop_db) |
342 | 1594 | { | 1594 | { |
343 | 1595 | XTDatabaseHPtr db = self->st_database; | 1595 | XTDatabaseHPtr db = self->st_database; |
344 | 1596 | XTOpenTablePoolPtr table_pool; | 1596 | XTOpenTablePoolPtr table_pool; |
345 | @@ -1614,7 +1614,7 @@ | |||
346 | 1614 | tab_id = tab->tab_id; /* tab is not null if returned table_pool is not null */ | 1614 | tab_id = tab->tab_id; /* tab is not null if returned table_pool is not null */ |
347 | 1615 | /* check if other tables refer this */ | 1615 | /* check if other tables refer this */ |
348 | 1616 | if (!self->st_ignore_fkeys) | 1616 | if (!self->st_ignore_fkeys) |
350 | 1617 | can_drop = tab->tab_dic.dic_table->checkCanDrop(); | 1617 | can_drop = tab->tab_dic.dic_table->checkCanDrop(drop_db); |
351 | 1618 | } | 1618 | } |
352 | 1619 | #ifdef DRIZZLED | 1619 | #ifdef DRIZZLED |
353 | 1620 | /* See the comment in ha_pbxt::delete_table regarding different implmentation of DROP TABLE | 1620 | /* See the comment in ha_pbxt::delete_table regarding different implmentation of DROP TABLE |
354 | 1621 | 1621 | ||
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 | 514 | int xt_use_table_by_id(struct XTThread *self, XTTableHPtr *tab, struct XTDatabase *db, xtTableID tab_id); | 514 | int xt_use_table_by_id(struct XTThread *self, XTTableHPtr *tab, struct XTDatabase *db, xtTableID tab_id); |
360 | 515 | XTOpenTablePtr xt_open_table(XTTableHPtr tab); | 515 | XTOpenTablePtr xt_open_table(XTTableHPtr tab); |
361 | 516 | void xt_close_table(XTOpenTablePtr ot, xtBool flush, xtBool have_table_lock); | 516 | void xt_close_table(XTOpenTablePtr ot, xtBool flush, xtBool have_table_lock); |
363 | 517 | void xt_drop_table(struct XTThread *self, XTPathStrPtr name); | 517 | void xt_drop_table(struct XTThread *self, XTPathStrPtr name, xtBool drop_db); |
364 | 518 | void xt_check_table(XTThreadPtr self, XTOpenTablePtr tab); | 518 | void xt_check_table(XTThreadPtr self, XTOpenTablePtr tab); |
365 | 519 | void xt_rename_table(struct XTThread *self, XTPathStrPtr old_name, XTPathStrPtr new_name); | 519 | void xt_rename_table(struct XTThread *self, XTPathStrPtr old_name, XTPathStrPtr new_name); |
366 | 520 | 520 | ||
367 | 521 | 521 | ||
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 | 1230 | 3 | 1230 | 3 |
373 | 1231 | 4 | 1231 | 4 |
374 | 1232 | drop table child, parent; | 1232 | drop table child, parent; |
375 | 1233 | create schema test378222; | ||
376 | 1234 | use test378222; | ||
377 | 1235 | create table t1 (id int primary key); | ||
378 | 1236 | create table t2 (id int primary key); | ||
379 | 1237 | alter table t1 add constraint foreign key (id) references t2 (id); | ||
380 | 1238 | alter table t2 add constraint foreign key (id) references t1 (id); | ||
381 | 1239 | drop schema test378222; | ||
382 | 1240 | create schema test378222a; | ||
383 | 1241 | create schema test378222b; | ||
384 | 1242 | create table test378222a.t1 (id int primary key) engine = pbxt; | ||
385 | 1243 | create table test378222b.t2 (id int primary key) engine = pbxt; | ||
386 | 1244 | alter table test378222a.t1 add constraint foreign key (id) references test378222b.t2 (id); | ||
387 | 1245 | alter table test378222b.t2 add constraint foreign key (id) references test378222a.t1 (id); | ||
388 | 1246 | set foreign_key_checks = 1; | ||
389 | 1247 | drop schema test378222a; | ||
390 | 1248 | ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails | ||
391 | 1249 | drop schema test378222b; | ||
392 | 1250 | ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails | ||
393 | 1251 | set foreign_key_checks = 0; | ||
394 | 1252 | drop schema test378222a; | ||
395 | 1253 | drop schema test378222b; | ||
396 | 1254 | set foreign_key_checks = 1; | ||
397 | 1233 | 1255 | ||
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 | 938 | 938 | ||
403 | 939 | drop table child, parent; | 939 | drop table child, parent; |
404 | 940 | 940 | ||
405 | 941 | # bug 378222: Drop sakila causes error: Cannot delete or update a parent row: a foreign key constraint fails | ||
406 | 942 | |||
407 | 943 | create schema test378222; | ||
408 | 944 | use test378222; | ||
409 | 945 | create table t1 (id int primary key); | ||
410 | 946 | create table t2 (id int primary key); | ||
411 | 947 | alter table t1 add constraint foreign key (id) references t2 (id); | ||
412 | 948 | alter table t2 add constraint foreign key (id) references t1 (id); | ||
413 | 949 | drop schema test378222; | ||
414 | 950 | |||
415 | 951 | create schema test378222a; | ||
416 | 952 | create schema test378222b; | ||
417 | 953 | create table test378222a.t1 (id int primary key) engine = pbxt; | ||
418 | 954 | create table test378222b.t2 (id int primary key) engine = pbxt; | ||
419 | 955 | alter table test378222a.t1 add constraint foreign key (id) references test378222b.t2 (id); | ||
420 | 956 | alter table test378222b.t2 add constraint foreign key (id) references test378222a.t1 (id); | ||
421 | 957 | set foreign_key_checks = 1; | ||
422 | 958 | --error 1217 | ||
423 | 959 | drop schema test378222a; | ||
424 | 960 | --error 1217 | ||
425 | 961 | drop schema test378222b; | ||
426 | 962 | set foreign_key_checks = 0; | ||
427 | 963 | drop schema test378222a; | ||
428 | 964 | drop schema test378222b; | ||
429 | 965 | set foreign_key_checks = 1; | ||
430 | 966 | |||
431 | 941 | --disable_query_log | 967 | --disable_query_log |
432 | 968 | use test; | ||
433 | 942 | DROP TABLE t2, t5; | 969 | DROP TABLE t2, t5; |
434 | 943 | drop database pbxt; | 970 | drop database pbxt; |
435 | 944 | --enable_query_log | 971 | --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