Merge lp:~laurynas-biveinis/percona-server/tokudb-multiple-clust-keys into lp:percona-server/5.6
- tokudb-multiple-clust-keys
- Merge into 5.6
Status: | Merged |
---|---|
Approved by: | Alexey Kopytov |
Approved revision: | no longer in the source branch. |
Merged at revision: | 571 |
Proposed branch: | lp:~laurynas-biveinis/percona-server/tokudb-multiple-clust-keys |
Merge into: | lp:percona-server/5.6 |
Diff against target: |
607 lines (+318/-27) 14 files modified
include/my_base.h (+3/-1) include/mysql_com.h (+2/-0) mysql-test/r/tokudb_clustering_key_grammar.result (+73/-0) mysql-test/t/tokudb_clustering_key_grammar.test (+99/-0) sql/handler.h (+5/-0) sql/lex.h (+1/-0) sql/sql_class.h (+2/-1) sql/sql_parse.cc (+12/-5) sql/sql_show.cc (+3/-0) sql/sql_table.cc (+25/-6) sql/sql_yacc.yy (+61/-11) sql/table.cc (+21/-1) sql/unireg.cc (+9/-1) tests/mysql_client_test.c (+2/-1) |
To merge this branch: | bzr merge lp:~laurynas-biveinis/percona-server/tokudb-multiple-clust-keys |
Related bugs: | |
Related blueprints: |
Multiple clustering keys
(High)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexey Kopytov (community) | Approve | ||
Laurynas Biveinis | Pending | ||
Review via email: mp+212834@code.launchpad.net |
This proposal supersedes a proposal from 2014-02-26.
Commit message
Description of the change
4th MP:
Disallow Key::CLUSTERING alone as a valid key type and enforce Key::MULTIPLE | Key::Clustering instead.
- add_field_to_list: add Key::MULTIPLE if needed
- mysql_prepare_
- parser unique_
- setup_key_
Rebase on the current trunk.
http://
3rd MP:
- If FRM contains SPATIAL | FULLTEXT key, check whether its SE supports clustered keys.
- Forbid UNIQUE UNIQUE and CLUSTERING CLUSTERING where UNIQUE CLUSTERING, CLUSTERING UNIQUE, UNIQUE, or CLUSTERING may appear. Add tests.
- Forbid CONSTRAINT c CLUSTERING, add tests.
- Add support for CLUSTERING as a field attribute, add tests.
http://
2nd MP:
- Extended the testcase to test CREATE CLUSTERING INDEX ON, to test
CLUSTERING in combination with UNIQUE (and CONSTRAINT if UNIQUE),
to test LOCK and ALGORITHM clauses for ALTER TABLE ADD INDEX, and
to test the same clauses without CLUSTERING.
- Declare new handlerton flag HTON_SUPPORTS_
- Assign values to enum Key::Keytype to support or'ing of enum
constants.
- In mysql_prepare_
Key::CLUSTERING and Key::UNIQUE in a same key->type. Check for
HTON_
HA_ILLEGAL_
- In mysql_prepare_
HA_NOSAME if both present in the same key_info->flags.
- In parser, replace opt_unique clause with opt_unique_
that allows UNIQUE, CLUSTERING, and a combination of the two where
previously only UNIQUE was allowed in key definitions and CREATE
INDEX statement. This also fixes a bug from the previous approach
which did not allow ALGORITHM and LOCK clauses for ALTER TABLE
... CLUSTERING ...
http://
1st MP:
Add support for CLUSTERING key type that is a clustering secondary
key, that is, the whole of the row can be accessed through the index
without going through the primary clustered index. This implements
the query parser and index definition persistence bits,
https:/
- New lexer symbol CLUSTERING, new key type in the grammar CREATE TABLE and
ALTER TABLE ADD INDEX clauses.
- New key type Key::Keytype:
INFORMATI
spatial and fulltext key types, handle this combination on FRM
read. This is to avoid a FRM format change.
- New testcase tokudb_
http://
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal | # |
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal | # |
Grammar rules for CLUSTERING do not include opt_index_
ALTER TABLE t1 ADD CLUSTERING INDEX b (b), LOCK=EXCLUSIVE, ALGORITHM=COPY;
syntax is not supported. It probably should be.
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal | # |
CREATE CLUSTERING INDEX b ON t1 (b)
syntax is not tested by the testcase.
CREATE CLUSTERING INDEX b ON t1 (b) LOCK=EXCLUSIVE ALGORITHM=COPY
fails with a parse error due to that missing opt_index_
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal | # |
> - s/INFORMATION_
> comment
Fixed.
> - I don’t think we should allow creation of non-TokuDB tables with
> secondary clustering keys. Otherwise once the optimizer support is
> reviewed and merged, we will get optimizer making incorrect
> assumptions about secondary clustering keys for tables that don’t
> actually implement it. On top of that, bad and hard-to-diagnose
> things may happen on downgrade or migration to another server
> flavor;
I agree and this was how I implemented it the first time before
Tokutek asked me to change to be treated as a hint. I didn't think of
downgrade/migration issues then or I wouldn't have changed. (I don't
see how the optimizer could make incorrect assumptions because no
other storage engine would return HA_CLUSTERING in index_flags()).
Added a handlerton flag HTON_SUPPORTS_
different from e.g. HA_CAN_RTREE etc, which are handler flags, but the
property of supporting clustered keys seems to me to be global and not
of table level for a SE.
For error message I reused ER_ILLEGAL_
engine 'InnoDB' does not support the create option 'CLUSTERING'")
> - I see there’s no support for UNIQUE CLUSTERING KEYs. Let’s fix it if
> it’s an oversight, or document if it’s a known limitation?
An oversight on my part, not sure about Tokutek. Syntax extended as
follows. Where previously "UNIQUE" was accepted as a valid modifier,
"CLUSTERING" is accepted too, as well as "UNIQUE CLUSTERING" and
"CLUSTERING UNIQUE":
- CREATE UNIQUE INDEX;
- as a part of key definition:
- CREATE TABLE (..., [CONSTRAINT ... ] UNIQUE KEY ...,)
- ALTER TABLE ADD [CONSTRAINT ...] UNIQUE KEY
The way the grammar was changed, it accepts "UNIQUE UNIQUE" and
"CLUSTERING CLUSTERING" too. IMHO benign.
Also now it is possible to create such "constraints" as CONSTRAINT c1
CLUSTERING KEY, which is not really a constraint at all, but again
IMHO benign and I don't see an easy way to forbid it without blowing
up shift/reduce conflict count in the parser.
One place where the syntax was not extended was field attribute
syntax:
- CREATE TABLE (..., b INT UNIQUE CLUSTERING KEY, ...).
It appeared to require more changes to the parser, and can be done in
a follow-up if really needed.
>
> - any specific reasons to add another reserved keyword to the
> parser?
I have reviewed the existing keywords and couldn't choose any IMHO
suitable replacement candidate. Also, I'm not sure Tokutek would
appreciate a forced mass search-replace in their testsuite that also
makes 5.5 to 5.6 upmerges less automatic.
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal | # |
>> - s/INFORMATION_
>> comment
>
> Fixed.
>
>> - I don’t think we should allow creation of non-TokuDB tables with
>> secondary clustering keys. Otherwise once the optimizer support is
>> reviewed and merged, we will get optimizer making incorrect
>> assumptions about secondary clustering keys for tables that don’t
>> actually implement it. On top of that, bad and hard-to-diagnose
>> things may happen on downgrade or migration to another server
>> flavor;
>
> I agree and this was how I implemented it the first time before
> Tokutek asked me to change to be treated as a hint. I didn't think of
> downgrade/migration issues then or I wouldn't have changed. (I don't
> see how the optimizer could make incorrect assumptions because no
> other storage engine would return HA_CLUSTERING in index_flags()).
>
The best way to handle this has been implemented in MariaDB via
SE-specific options in CREATE/ALTER. I doubt we should port those
extensions as a part of this work, just pointing out that the way we are
implementing it will inevitably have unwanted side effects.
Wrt optimizer changes: there’s code in the optimizer that takes flags
from key definition into account (rather than just flags returned by the
storage engine). For example, some code checks key definition flags and
assumes it to be a regular key if none if the previous checks for
specific flags return true. If you allow CLUSTERING keys for storage
engine that don’t support them, you still get the HA_CLUSTERING key set
in key definition flags.
> Added a handlerton flag HTON_SUPPORTS_
> different from e.g. HA_CAN_RTREE etc, which are handler flags, but the
> property of supporting clustered keys seems to me to be global and not
> of table level for a SE.
>
> For error message I reused ER_ILLEGAL_
> engine 'InnoDB' does not support the create option 'CLUSTERING'")
>
That looks good in general. Please also add code that enforces this
restriction to open_binary_frm(). I.e. it should fail with an error if a
non-InnoDB table happens to contain both HA_SPATIAL and HA_FULLTEXT
flags for an index.
>> - I see there’s no support for UNIQUE CLUSTERING KEYs. Let’s fix it if
>> it’s an oversight, or document if it’s a known limitation?
>
> An oversight on my part, not sure about Tokutek. Syntax extended as
Are you going to report it to Tokutek?
> follows. Where previously "UNIQUE" was accepted as a valid modifier,
> "CLUSTERING" is accepted too, as well as "UNIQUE CLUSTERING" and
> "CLUSTERING UNIQUE":
> - CREATE UNIQUE INDEX;
> - as a part of key definition:
> - CREATE TABLE (..., [CONSTRAINT ... ] UNIQUE KEY ...,)
> - ALTER TABLE ADD [CONSTRAINT ...] UNIQUE KEY
>
> The way the grammar was changed, it accepts "UNIQUE UNIQUE" and
> "CLUSTERING CLUSTERING" too. IMHO benign.
>
Hm, doesn’t look that benign to me. UNIQUE UNIQUE is invalid SQL which a
user may want to be aware of. It would be aware before the change. It
will not be aware after the change.
> Also now it is possible to create such "constraints" as CONSTRAINT c1
> CLUSTERING KEY, which is not really a constraint at a...
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal | # |
> The best way to handle this has been implemented in MariaDB via
> SE-specific options in CREATE/ALTER. I doubt we should port those
> extensions as a part of this work, just pointing out that the way we are
> implementing it will inevitably have unwanted side effects.
Fully agreed.
> Wrt optimizer changes: there’s code in the optimizer that takes flags
> from key definition into account (rather than just flags returned by the
> storage engine). For example, some code checks key definition flags and
> assumes it to be a regular key if none if the previous checks for
> specific flags return true. If you allow CLUSTERING keys for storage
> engine that don’t support them, you still get the HA_CLUSTERING key set
> in key definition flags.
OK, I see.
> > Added a handlerton flag HTON_SUPPORTS_
> > different from e.g. HA_CAN_RTREE etc, which are handler flags, but the
> > property of supporting clustered keys seems to me to be global and not
> > of table level for a SE.
> >
> > For error message I reused ER_ILLEGAL_
> > engine 'InnoDB' does not support the create option 'CLUSTERING'")
> >
>
> That looks good in general. Please also add code that enforces this
> restriction to open_binary_frm(). I.e. it should fail with an error if a
> non-InnoDB table happens to contain both HA_SPATIAL and HA_FULLTEXT
> flags for an index.
Done. Should this happen, it should return ER_NOT_FORM_FILE.
> >> - I see there’s no support for UNIQUE CLUSTERING KEYs. Let’s fix it if
> >> it’s an oversight, or document if it’s a known limitation?
> >
> > An oversight on my part, not sure about Tokutek. Syntax extended as
>
> Are you going to report it to Tokutek?
Yes.
> > follows. Where previously "UNIQUE" was accepted as a valid modifier,
> > "CLUSTERING" is accepted too, as well as "UNIQUE CLUSTERING" and
> > "CLUSTERING UNIQUE":
> > - CREATE UNIQUE INDEX;
> > - as a part of key definition:
> > - CREATE TABLE (..., [CONSTRAINT ... ] UNIQUE KEY ...,)
> > - ALTER TABLE ADD [CONSTRAINT ...] UNIQUE KEY
> >
> > The way the grammar was changed, it accepts "UNIQUE UNIQUE" and
> > "CLUSTERING CLUSTERING" too. IMHO benign.
> >
>
> Hm, doesn’t look that benign to me. UNIQUE UNIQUE is invalid SQL which a
> user may want to be aware of. It would be aware before the change. It
> will not be aware after the change.
OK, fixed, added tests too.
> > Also now it is possible to create such "constraints" as CONSTRAINT c1
> > CLUSTERING KEY, which is not really a constraint at all, but again
> > IMHO benign and I don't see an easy way to forbid it without blowing
> > up shift/reduce conflict count in the parser.
> >
>
> I don’t see a point in supporting CONSTRAINT c1 CLUSTERING KEY.
I don't see a point neither, but "constraint" is hard to distinguish
from "key" in the parser grammar, so it was a side effect of adding
clustering support for the keys. I have tried two fixes. One was
based on syntax changes only, but I couldn't avoid bumping
shift/reduce conflict count. Thus I settled for a semantic action
hack. There are some differences in error reporting between the two
("-" is the syntactical fix, "+" the pushed seman...
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal | # |
Rebased on the current trunk. No changes.
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal | # |
Allowing to OR Key::Keytype flags together (Keytype:
- add_field_to_list: add Key::MULTIPLE if needed
- mysql_prepare_
- parser unique_
- setup_key_
Alexey Kopytov (akopytov) : | # |
Preview Diff
1 | === modified file 'include/my_base.h' | |||
2 | --- include/my_base.h 2014-02-17 11:12:40 +0000 | |||
3 | +++ include/my_base.h 2014-03-26 12:37:51 +0000 | |||
4 | @@ -258,11 +258,13 @@ | |||
5 | 258 | #define HA_SPATIAL 1024 /* For spatial search */ | 258 | #define HA_SPATIAL 1024 /* For spatial search */ |
6 | 259 | #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ | 259 | #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ |
7 | 260 | #define HA_GENERATED_KEY 8192 /* Automaticly generated key */ | 260 | #define HA_GENERATED_KEY 8192 /* Automaticly generated key */ |
8 | 261 | #define HA_CLUSTERING (1<<31) /* TokuDB CLUSTERING key */ | ||
9 | 261 | 262 | ||
10 | 262 | /* The combination of the above can be used for key type comparison. */ | 263 | /* The combination of the above can be used for key type comparison. */ |
11 | 263 | #define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \ | 264 | #define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \ |
12 | 264 | HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \ | 265 | HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \ |
14 | 265 | HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY) | 266 | HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY | \ |
15 | 267 | HA_CLUSTERING) | ||
16 | 266 | 268 | ||
17 | 267 | /* | 269 | /* |
18 | 268 | Key contains partial segments. | 270 | Key contains partial segments. |
19 | 269 | 271 | ||
20 | === modified file 'include/mysql_com.h' | |||
21 | --- include/mysql_com.h 2013-08-14 03:57:21 +0000 | |||
22 | +++ include/mysql_com.h 2014-03-26 12:37:51 +0000 | |||
23 | @@ -126,6 +126,8 @@ | |||
24 | 126 | #define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25 */ | 126 | #define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25 */ |
25 | 127 | #define FIELD_FLAGS_COLUMN_FORMAT_MASK (3 << FIELD_FLAGS_COLUMN_FORMAT) | 127 | #define FIELD_FLAGS_COLUMN_FORMAT_MASK (3 << FIELD_FLAGS_COLUMN_FORMAT) |
26 | 128 | #define FIELD_IS_DROPPED (1<< 26) /* Intern: Field is being dropped */ | 128 | #define FIELD_IS_DROPPED (1<< 26) /* Intern: Field is being dropped */ |
27 | 129 | #define CLUSTERING_FLAG (1 << 27) /* Field has a secondary clustering | ||
28 | 130 | key */ | ||
29 | 129 | 131 | ||
30 | 130 | #define REFRESH_GRANT 1 /* Refresh grant tables */ | 132 | #define REFRESH_GRANT 1 /* Refresh grant tables */ |
31 | 131 | #define REFRESH_LOG 2 /* Start on new log file */ | 133 | #define REFRESH_LOG 2 /* Start on new log file */ |
32 | 132 | 134 | ||
33 | === added file 'mysql-test/r/tokudb_clustering_key_grammar.result' | |||
34 | --- mysql-test/r/tokudb_clustering_key_grammar.result 1970-01-01 00:00:00 +0000 | |||
35 | +++ mysql-test/r/tokudb_clustering_key_grammar.result 2014-03-26 12:37:51 +0000 | |||
36 | @@ -0,0 +1,73 @@ | |||
37 | 1 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
38 | 2 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
39 | 3 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; | ||
40 | 4 | ALTER TABLE t1 ADD CLUSTERING INDEX b (b); | ||
41 | 5 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
42 | 6 | CREATE CLUSTERING INDEX b ON t1 (b) LOCK=EXCLUSIVE ALGORITHM=COPY; | ||
43 | 7 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
44 | 8 | ALTER TABLE t1 ADD CLUSTERING INDEX b (b), LOCK=EXCLUSIVE, ALGORITHM=COPY; | ||
45 | 9 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
46 | 10 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, UNIQUE CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
47 | 11 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
48 | 12 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, UNIQUE UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
49 | 13 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNIQUE KEY b (b)) ENGINE=InnoDB' at line 1 | ||
50 | 14 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CLUSTERING CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
51 | 15 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CLUSTERING KEY b (b)) ENGINE=InnoDB' at line 1 | ||
52 | 16 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CLUSTERING UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
53 | 17 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
54 | 18 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 UNIQUE CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
55 | 19 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
56 | 20 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 CLUSTERING UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
57 | 21 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
58 | 22 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 UNIQUE UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
59 | 23 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNIQUE KEY b (b)) ENGINE=InnoDB' at line 1 | ||
60 | 24 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
61 | 25 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ENGINE=InnoDB' at line 1 | ||
62 | 26 | ALTER TABLE t1 ADD UNIQUE CLUSTERING INDEX b (b); | ||
63 | 27 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
64 | 28 | ALTER TABLE t1 ADD CLUSTERING UNIQUE INDEX b (b); | ||
65 | 29 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
66 | 30 | ALTER TABLE t1 ADD UNIQUE UNIQUE INDEX b (b); | ||
67 | 31 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNIQUE INDEX b (b)' at line 1 | ||
68 | 32 | ALTER TABLE t1 ADD CLUSTERING CLUSTERING INDEX b (b); | ||
69 | 33 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CLUSTERING INDEX b (b)' at line 1 | ||
70 | 34 | ALTER TABLE t1 ADD CONSTRAINT c1 UNIQUE CLUSTERING INDEX b (b); | ||
71 | 35 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
72 | 36 | ALTER TABLE t1 ADD CONSTRAINT c1 CLUSTERING UNIQUE INDEX b (b); | ||
73 | 37 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
74 | 38 | ALTER TABLE t1 ADD CONSTRAINT c1 UNIQUE UNIQUE INDEX b (b); | ||
75 | 39 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNIQUE INDEX b (b)' at line 1 | ||
76 | 40 | ALTER TABLE t1 ADD CONSTRAINT c1 CLUSTERING INDEX b (b); | ||
77 | 41 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 | ||
78 | 42 | DROP TABLE t1; | ||
79 | 43 | CREATE TABLE t1 (a INT CLUSTERING) ENGINE=InnoDB; | ||
80 | 44 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
81 | 45 | CREATE TABLE t1 (a INT CLUSTERING KEY) ENGINE=InnoDB; | ||
82 | 46 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
83 | 47 | CREATE TABLE t1 (a INT CLUSTERING UNIQUE) ENGINE=InnoDB; | ||
84 | 48 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
85 | 49 | CREATE TABLE t1 (a INT CLUSTERING UNIQUE KEY) ENGINE=InnoDB; | ||
86 | 50 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
87 | 51 | CREATE TABLE t1 (a INT UNIQUE CLUSTERING) ENGINE=InnoDB; | ||
88 | 52 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
89 | 53 | CREATE TABLE t1 (a INT UNIQUE CLUSTERING KEY) ENGINE=InnoDB; | ||
90 | 54 | ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'CLUSTERING' | ||
91 | 55 | CREATE TABLE CLUSTERING(a INT) ENGINE=InnoDB; | ||
92 | 56 | ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CLUSTERING(a INT) ENGINE=InnoDB' at line 1 | ||
93 | 57 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, d INT, e INT, f INT, g INT, UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
94 | 58 | ALTER TABLE t1 ADD UNIQUE INDEX c (c), LOCK=EXCLUSIVE, ALGORITHM=COPY; | ||
95 | 59 | ALTER TABLE t1 ADD CONSTRAINT c1 UNIQUE INDEX g (g); | ||
96 | 60 | ALTER TABLE t1 ADD INDEX d (d); | ||
97 | 61 | CREATE INDEX e ON t1 (e) LOCK=EXCLUSIVE ALGORITHM=COPY; | ||
98 | 62 | CREATE UNIQUE INDEX f ON t1 (f); | ||
99 | 63 | DROP TABLE t1; | ||
100 | 64 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY b (b)) ENGINE=InnoDB; | ||
101 | 65 | DROP TABLE t1; | ||
102 | 66 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, UNIQUE b (b)) ENGINE=InnoDB; | ||
103 | 67 | DROP TABLE t1; | ||
104 | 68 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 UNIQUE b (b)) ENGINE=InnoDB; | ||
105 | 69 | DROP TABLE t1; | ||
106 | 70 | CREATE TABLE t1 (a INT UNIQUE) ENGINE=InnoDB; | ||
107 | 71 | DROP TABLE t1; | ||
108 | 72 | CREATE TABLE t1 (a INT UNIQUE KEY) ENGINE=InnoDB; | ||
109 | 73 | DROP TABLE t1; | ||
110 | 0 | 74 | ||
111 | === added file 'mysql-test/t/tokudb_clustering_key_grammar.test' | |||
112 | --- mysql-test/t/tokudb_clustering_key_grammar.test 1970-01-01 00:00:00 +0000 | |||
113 | +++ mysql-test/t/tokudb_clustering_key_grammar.test 2014-03-26 12:37:51 +0000 | |||
114 | @@ -0,0 +1,99 @@ | |||
115 | 1 | # | ||
116 | 2 | # Test that TokuDB CLUSTERING key grammar addition syntax is understood (does not fail with | ||
117 | 3 | # ER_PARSE_ERROR), but that non-supporting storage engines reject it by returning | ||
118 | 4 | # ER_ILLEGAL_HA_CREATE_OPTION. | ||
119 | 5 | # | ||
120 | 6 | --source include/have_innodb.inc | ||
121 | 7 | |||
122 | 8 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
123 | 9 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
124 | 10 | |||
125 | 11 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; | ||
126 | 12 | |||
127 | 13 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
128 | 14 | ALTER TABLE t1 ADD CLUSTERING INDEX b (b); | ||
129 | 15 | |||
130 | 16 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
131 | 17 | CREATE CLUSTERING INDEX b ON t1 (b) LOCK=EXCLUSIVE ALGORITHM=COPY; | ||
132 | 18 | |||
133 | 19 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
134 | 20 | ALTER TABLE t1 ADD CLUSTERING INDEX b (b), LOCK=EXCLUSIVE, ALGORITHM=COPY; | ||
135 | 21 | |||
136 | 22 | # CLUSTERING can be combined with UNIQUE, but neither of them can be combined with itself. | ||
137 | 23 | # CLUSTERING cannot be the sole key type for a CONSTRAINT. | ||
138 | 24 | |||
139 | 25 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
140 | 26 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, UNIQUE CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
141 | 27 | --error ER_PARSE_ERROR | ||
142 | 28 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, UNIQUE UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
143 | 29 | --error ER_PARSE_ERROR | ||
144 | 30 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CLUSTERING CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
145 | 31 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
146 | 32 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CLUSTERING UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
147 | 33 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
148 | 34 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 UNIQUE CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
149 | 35 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
150 | 36 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 CLUSTERING UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
151 | 37 | --error ER_PARSE_ERROR | ||
152 | 38 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 UNIQUE UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
153 | 39 | --error ER_PARSE_ERROR | ||
154 | 40 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 CLUSTERING KEY b (b)) ENGINE=InnoDB; | ||
155 | 41 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
156 | 42 | ALTER TABLE t1 ADD UNIQUE CLUSTERING INDEX b (b); | ||
157 | 43 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
158 | 44 | ALTER TABLE t1 ADD CLUSTERING UNIQUE INDEX b (b); | ||
159 | 45 | --error ER_PARSE_ERROR | ||
160 | 46 | ALTER TABLE t1 ADD UNIQUE UNIQUE INDEX b (b); | ||
161 | 47 | --error ER_PARSE_ERROR | ||
162 | 48 | ALTER TABLE t1 ADD CLUSTERING CLUSTERING INDEX b (b); | ||
163 | 49 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
164 | 50 | ALTER TABLE t1 ADD CONSTRAINT c1 UNIQUE CLUSTERING INDEX b (b); | ||
165 | 51 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
166 | 52 | ALTER TABLE t1 ADD CONSTRAINT c1 CLUSTERING UNIQUE INDEX b (b); | ||
167 | 53 | --error ER_PARSE_ERROR | ||
168 | 54 | ALTER TABLE t1 ADD CONSTRAINT c1 UNIQUE UNIQUE INDEX b (b); | ||
169 | 55 | --error ER_PARSE_ERROR | ||
170 | 56 | ALTER TABLE t1 ADD CONSTRAINT c1 CLUSTERING INDEX b (b); | ||
171 | 57 | |||
172 | 58 | DROP TABLE t1; | ||
173 | 59 | |||
174 | 60 | # Test CLUSTERING as a field attribute, alone and in combination with UNIQUE | ||
175 | 61 | |||
176 | 62 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
177 | 63 | CREATE TABLE t1 (a INT CLUSTERING) ENGINE=InnoDB; | ||
178 | 64 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
179 | 65 | CREATE TABLE t1 (a INT CLUSTERING KEY) ENGINE=InnoDB; | ||
180 | 66 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
181 | 67 | CREATE TABLE t1 (a INT CLUSTERING UNIQUE) ENGINE=InnoDB; | ||
182 | 68 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
183 | 69 | CREATE TABLE t1 (a INT CLUSTERING UNIQUE KEY) ENGINE=InnoDB; | ||
184 | 70 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
185 | 71 | CREATE TABLE t1 (a INT UNIQUE CLUSTERING) ENGINE=InnoDB; | ||
186 | 72 | --error ER_ILLEGAL_HA_CREATE_OPTION | ||
187 | 73 | CREATE TABLE t1 (a INT UNIQUE CLUSTERING KEY) ENGINE=InnoDB; | ||
188 | 74 | |||
189 | 75 | # CLUSTERING is not allowed as an identifier due to causing extra shift/reduce parser conflicts | ||
190 | 76 | --error ER_PARSE_ERROR | ||
191 | 77 | CREATE TABLE CLUSTERING(a INT) ENGINE=InnoDB; | ||
192 | 78 | |||
193 | 79 | |||
194 | 80 | # Check that the grammar changes have not broken related CLUSTERING-less clauses | ||
195 | 81 | |||
196 | 82 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, d INT, e INT, f INT, g INT, UNIQUE KEY b (b)) ENGINE=InnoDB; | ||
197 | 83 | ALTER TABLE t1 ADD UNIQUE INDEX c (c), LOCK=EXCLUSIVE, ALGORITHM=COPY; | ||
198 | 84 | ALTER TABLE t1 ADD CONSTRAINT c1 UNIQUE INDEX g (g); | ||
199 | 85 | ALTER TABLE t1 ADD INDEX d (d); | ||
200 | 86 | CREATE INDEX e ON t1 (e) LOCK=EXCLUSIVE ALGORITHM=COPY; | ||
201 | 87 | CREATE UNIQUE INDEX f ON t1 (f); | ||
202 | 88 | DROP TABLE t1; | ||
203 | 89 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY b (b)) ENGINE=InnoDB; | ||
204 | 90 | DROP TABLE t1; | ||
205 | 91 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, UNIQUE b (b)) ENGINE=InnoDB; | ||
206 | 92 | DROP TABLE t1; | ||
207 | 93 | CREATE TABLE t1 (a INT PRIMARY KEY, b INT, CONSTRAINT c1 UNIQUE b (b)) ENGINE=InnoDB; | ||
208 | 94 | DROP TABLE t1; | ||
209 | 95 | |||
210 | 96 | CREATE TABLE t1 (a INT UNIQUE) ENGINE=InnoDB; | ||
211 | 97 | DROP TABLE t1; | ||
212 | 98 | CREATE TABLE t1 (a INT UNIQUE KEY) ENGINE=InnoDB; | ||
213 | 99 | DROP TABLE t1; | ||
214 | 0 | 100 | ||
215 | === modified file 'sql/handler.h' | |||
216 | --- sql/handler.h 2014-02-27 12:29:47 +0000 | |||
217 | +++ sql/handler.h 2014-03-26 12:37:51 +0000 | |||
218 | @@ -1031,6 +1031,11 @@ | |||
219 | 1031 | */ | 1031 | */ |
220 | 1032 | #define HTON_SUPPORTS_ONLINE_BACKUPS (1 << 11) | 1032 | #define HTON_SUPPORTS_ONLINE_BACKUPS (1 << 11) |
221 | 1033 | 1033 | ||
222 | 1034 | /** | ||
223 | 1035 | Engine supports secondary clustered keys. | ||
224 | 1036 | */ | ||
225 | 1037 | #define HTON_SUPPORTS_CLUSTERED_KEYS (1 << 12) | ||
226 | 1038 | |||
227 | 1034 | enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, | 1039 | enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, |
228 | 1035 | ISO_REPEATABLE_READ, ISO_SERIALIZABLE}; | 1040 | ISO_REPEATABLE_READ, ISO_SERIALIZABLE}; |
229 | 1036 | 1041 | ||
230 | 1037 | 1042 | ||
231 | === modified file 'sql/lex.h' | |||
232 | --- sql/lex.h 2013-12-16 12:54:12 +0000 | |||
233 | +++ sql/lex.h 2014-03-26 12:37:51 +0000 | |||
234 | @@ -115,6 +115,7 @@ | |||
235 | 115 | { "CLIENT", SYM(CLIENT_SYM)}, | 115 | { "CLIENT", SYM(CLIENT_SYM)}, |
236 | 116 | { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)}, | 116 | { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)}, |
237 | 117 | { "CLOSE", SYM(CLOSE_SYM)}, | 117 | { "CLOSE", SYM(CLOSE_SYM)}, |
238 | 118 | { "CLUSTERING", SYM(CLUSTERING_SYM)}, | ||
239 | 118 | { "COALESCE", SYM(COALESCE)}, | 119 | { "COALESCE", SYM(COALESCE)}, |
240 | 119 | { "CODE", SYM(CODE_SYM)}, | 120 | { "CODE", SYM(CODE_SYM)}, |
241 | 120 | { "COLLATE", SYM(COLLATE_SYM)}, | 121 | { "COLLATE", SYM(COLLATE_SYM)}, |
242 | 121 | 122 | ||
243 | === modified file 'sql/sql_class.h' | |||
244 | --- sql/sql_class.h 2014-03-03 17:51:33 +0000 | |||
245 | +++ sql/sql_class.h 2014-03-26 12:37:51 +0000 | |||
246 | @@ -294,7 +294,8 @@ | |||
247 | 294 | 294 | ||
248 | 295 | class Key :public Sql_alloc { | 295 | class Key :public Sql_alloc { |
249 | 296 | public: | 296 | public: |
251 | 297 | enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; | 297 | enum Keytype { PRIMARY= 0, UNIQUE= 1, MULTIPLE= 2, FULLTEXT= 4, SPATIAL= 8, |
252 | 298 | FOREIGN_KEY= 16, CLUSTERING= 32 }; | ||
253 | 298 | enum Keytype type; | 299 | enum Keytype type; |
254 | 299 | KEY_CREATE_INFO key_create_info; | 300 | KEY_CREATE_INFO key_create_info; |
255 | 300 | List<Key_part_spec> columns; | 301 | List<Key_part_spec> columns; |
256 | 301 | 302 | ||
257 | === modified file 'sql/sql_parse.cc' | |||
258 | --- sql/sql_parse.cc 2014-03-17 07:06:47 +0000 | |||
259 | +++ sql/sql_parse.cc 2014-03-26 12:37:51 +0000 | |||
260 | @@ -6921,13 +6921,20 @@ | |||
261 | 6921 | lex->alter_info.key_list.push_back(key); | 6921 | lex->alter_info.key_list.push_back(key); |
262 | 6922 | lex->col_list.empty(); | 6922 | lex->col_list.empty(); |
263 | 6923 | } | 6923 | } |
265 | 6924 | if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) | 6924 | if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG | CLUSTERING_FLAG)) |
266 | 6925 | { | 6925 | { |
268 | 6926 | Key *key; | 6926 | Key::Keytype keytype; |
269 | 6927 | if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) | ||
270 | 6928 | keytype= Key::UNIQUE; | ||
271 | 6929 | else | ||
272 | 6930 | keytype= Key::MULTIPLE; | ||
273 | 6931 | if (type_modifier & CLUSTERING_FLAG) | ||
274 | 6932 | keytype= (enum Key::Keytype)(keytype | Key::CLUSTERING); | ||
275 | 6933 | DBUG_ASSERT(keytype != Key::MULTIPLE); | ||
276 | 6934 | |||
277 | 6927 | lex->col_list.push_back(new Key_part_spec(*field_name, 0)); | 6935 | lex->col_list.push_back(new Key_part_spec(*field_name, 0)); |
281 | 6928 | key= new Key(Key::UNIQUE, null_lex_str, | 6936 | Key *key= new Key(keytype, null_lex_str, &default_key_create_info, 0, |
282 | 6929 | &default_key_create_info, 0, | 6937 | lex->col_list); |
280 | 6930 | lex->col_list); | ||
283 | 6931 | lex->alter_info.key_list.push_back(key); | 6938 | lex->alter_info.key_list.push_back(key); |
284 | 6932 | lex->col_list.empty(); | 6939 | lex->col_list.empty(); |
285 | 6933 | } | 6940 | } |
286 | 6934 | 6941 | ||
287 | === modified file 'sql/sql_show.cc' | |||
288 | --- sql/sql_show.cc 2014-03-03 17:51:33 +0000 | |||
289 | +++ sql/sql_show.cc 2014-03-26 12:37:51 +0000 | |||
290 | @@ -1525,6 +1525,8 @@ | |||
291 | 1525 | packet->append(STRING_WITH_LEN("FULLTEXT KEY ")); | 1525 | packet->append(STRING_WITH_LEN("FULLTEXT KEY ")); |
292 | 1526 | else if (key_info->flags & HA_SPATIAL) | 1526 | else if (key_info->flags & HA_SPATIAL) |
293 | 1527 | packet->append(STRING_WITH_LEN("SPATIAL KEY ")); | 1527 | packet->append(STRING_WITH_LEN("SPATIAL KEY ")); |
294 | 1528 | else if (key_info->flags & HA_CLUSTERING) | ||
295 | 1529 | packet->append(STRING_WITH_LEN("CLUSTERING KEY ")); | ||
296 | 1528 | else | 1530 | else |
297 | 1529 | packet->append(STRING_WITH_LEN("KEY ")); | 1531 | packet->append(STRING_WITH_LEN("KEY ")); |
298 | 1530 | 1532 | ||
299 | @@ -5227,6 +5229,7 @@ | |||
300 | 5227 | store_column_type(table, field, cs, IS_COLUMNS_DATA_TYPE); | 5229 | store_column_type(table, field, cs, IS_COLUMNS_DATA_TYPE); |
301 | 5228 | pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" : | 5230 | pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" : |
302 | 5229 | (field->flags & UNIQUE_KEY_FLAG) ? "UNI" : | 5231 | (field->flags & UNIQUE_KEY_FLAG) ? "UNI" : |
303 | 5232 | (field->flags & CLUSTERING_FLAG) ? "CLU" : | ||
304 | 5230 | (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); | 5233 | (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); |
305 | 5231 | table->field[IS_COLUMNS_COLUMN_KEY]->store((const char*) pos, | 5234 | table->field[IS_COLUMNS_COLUMN_KEY]->store((const char*) pos, |
306 | 5232 | strlen((const char*) pos), cs); | 5235 | strlen((const char*) pos), cs); |
307 | 5233 | 5236 | ||
308 | === modified file 'sql/sql_table.cc' | |||
309 | --- sql/sql_table.cc 2014-02-17 11:12:40 +0000 | |||
310 | +++ sql/sql_table.cc 2014-03-26 12:37:51 +0000 | |||
311 | @@ -3757,7 +3757,7 @@ | |||
312 | 3757 | break; | 3757 | break; |
313 | 3758 | } | 3758 | } |
314 | 3759 | 3759 | ||
316 | 3760 | switch (key->type) { | 3760 | switch ((unsigned)key->type) { |
317 | 3761 | case Key::MULTIPLE: | 3761 | case Key::MULTIPLE: |
318 | 3762 | key_info->flags= 0; | 3762 | key_info->flags= 0; |
319 | 3763 | break; | 3763 | break; |
320 | @@ -3780,6 +3780,23 @@ | |||
321 | 3780 | case Key::FOREIGN_KEY: | 3780 | case Key::FOREIGN_KEY: |
322 | 3781 | key_number--; // Skip this key | 3781 | key_number--; // Skip this key |
323 | 3782 | continue; | 3782 | continue; |
324 | 3783 | case Key::CLUSTERING | Key::UNIQUE: | ||
325 | 3784 | case Key::CLUSTERING | Key::MULTIPLE: | ||
326 | 3785 | if (unlikely(!ha_check_storage_engine_flag( | ||
327 | 3786 | file->ht, HTON_SUPPORTS_CLUSTERED_KEYS))) | ||
328 | 3787 | { | ||
329 | 3788 | my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0), | ||
330 | 3789 | ha_resolve_storage_engine_name(file->ht), "CLUSTERING"); | ||
331 | 3790 | DBUG_RETURN(TRUE); | ||
332 | 3791 | } | ||
333 | 3792 | if (key->type & Key::UNIQUE) | ||
334 | 3793 | key_info->flags= HA_NOSAME; | ||
335 | 3794 | else | ||
336 | 3795 | key_info->flags= 0; | ||
337 | 3796 | key_info->flags|= HA_CLUSTERING; | ||
338 | 3797 | break; | ||
339 | 3798 | case Key::CLUSTERING: | ||
340 | 3799 | DBUG_ASSERT(0); | ||
341 | 3783 | default: | 3800 | default: |
342 | 3784 | key_info->flags = HA_NOSAME; | 3801 | key_info->flags = HA_NOSAME; |
343 | 3785 | break; | 3802 | break; |
344 | @@ -4021,7 +4038,7 @@ | |||
345 | 4021 | key_part_length= min(max_key_length, file->max_key_part_length()); | 4038 | key_part_length= min(max_key_length, file->max_key_part_length()); |
346 | 4022 | if (max_field_size) | 4039 | if (max_field_size) |
347 | 4023 | key_part_length= min(key_part_length, max_field_size); | 4040 | key_part_length= min(key_part_length, max_field_size); |
349 | 4024 | if (key->type == Key::MULTIPLE) | 4041 | if (key->type & Key::MULTIPLE) |
350 | 4025 | { | 4042 | { |
351 | 4026 | /* not a critical problem */ | 4043 | /* not a critical problem */ |
352 | 4027 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, | 4044 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
353 | @@ -4073,7 +4090,7 @@ | |||
354 | 4073 | key->type != Key::FULLTEXT) | 4090 | key->type != Key::FULLTEXT) |
355 | 4074 | { | 4091 | { |
356 | 4075 | key_part_length= file->max_key_part_length(); | 4092 | key_part_length= file->max_key_part_length(); |
358 | 4076 | if (key->type == Key::MULTIPLE) | 4093 | if (key->type & Key::MULTIPLE) |
359 | 4077 | { | 4094 | { |
360 | 4078 | /* not a critical problem */ | 4095 | /* not a critical problem */ |
361 | 4079 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, | 4096 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
362 | @@ -7235,7 +7252,9 @@ | |||
363 | 7235 | key_type= Key::FULLTEXT; | 7252 | key_type= Key::FULLTEXT; |
364 | 7236 | else | 7253 | else |
365 | 7237 | key_type= Key::MULTIPLE; | 7254 | key_type= Key::MULTIPLE; |
367 | 7238 | 7255 | if (key_info->flags & HA_CLUSTERING) | |
368 | 7256 | key_type= (enum Key::Keytype)(key_type | Key::CLUSTERING); | ||
369 | 7257 | |||
370 | 7239 | if (index_column_dropped) | 7258 | if (index_column_dropped) |
371 | 7240 | { | 7259 | { |
372 | 7241 | /* | 7260 | /* |
373 | @@ -7251,7 +7270,7 @@ | |||
374 | 7251 | key_parts); | 7270 | key_parts); |
375 | 7252 | new_key_list.push_back(key); | 7271 | new_key_list.push_back(key); |
376 | 7253 | 7272 | ||
378 | 7254 | if (skip_secondary && key_type == Key::MULTIPLE) { | 7273 | if (skip_secondary && key_type & Key::MULTIPLE) { |
379 | 7255 | delayed_key_list.push_back(key); | 7274 | delayed_key_list.push_back(key); |
380 | 7256 | } | 7275 | } |
381 | 7257 | } | 7276 | } |
382 | @@ -7264,7 +7283,7 @@ | |||
383 | 7264 | 7283 | ||
384 | 7265 | if (key->type != Key::FOREIGN_KEY) | 7284 | if (key->type != Key::FOREIGN_KEY) |
385 | 7266 | { | 7285 | { |
387 | 7267 | if (skip_secondary && key->type == Key::MULTIPLE) { | 7286 | if (skip_secondary && key->type & Key::MULTIPLE) { |
388 | 7268 | delayed_key_list.push_back(key); | 7287 | delayed_key_list.push_back(key); |
389 | 7269 | } | 7288 | } |
390 | 7270 | } | 7289 | } |
391 | 7271 | 7290 | ||
392 | === modified file 'sql/sql_yacc.yy' | |||
393 | --- sql/sql_yacc.yy 2014-02-25 07:30:22 +0000 | |||
394 | +++ sql/sql_yacc.yy 2014-03-26 12:37:51 +0000 | |||
395 | @@ -1029,7 +1029,7 @@ | |||
396 | 1029 | Currently there are 161 shift/reduce conflicts. | 1029 | Currently there are 161 shift/reduce conflicts. |
397 | 1030 | We should not introduce new conflicts any more. | 1030 | We should not introduce new conflicts any more. |
398 | 1031 | */ | 1031 | */ |
400 | 1032 | %expect 162 | 1032 | %expect 164 |
401 | 1033 | 1033 | ||
402 | 1034 | /* | 1034 | /* |
403 | 1035 | Comments for TOKENS. | 1035 | Comments for TOKENS. |
404 | @@ -1114,6 +1114,7 @@ | |||
405 | 1114 | %token CLIENT_SYM | 1114 | %token CLIENT_SYM |
406 | 1115 | %token CLIENT_STATS_SYM | 1115 | %token CLIENT_STATS_SYM |
407 | 1116 | %token CLOSE_SYM /* SQL-2003-R */ | 1116 | %token CLOSE_SYM /* SQL-2003-R */ |
408 | 1117 | %token CLUSTERING_SYM | ||
409 | 1117 | %token COALESCE /* SQL-2003-N */ | 1118 | %token COALESCE /* SQL-2003-N */ |
410 | 1118 | %token CODE_SYM | 1119 | %token CODE_SYM |
411 | 1119 | %token COLLATE_SYM /* SQL-2003-R */ | 1120 | %token COLLATE_SYM /* SQL-2003-R */ |
412 | @@ -1794,7 +1795,8 @@ | |||
413 | 1794 | option_type opt_var_type opt_var_ident_type | 1795 | option_type opt_var_type opt_var_ident_type |
414 | 1795 | 1796 | ||
415 | 1796 | %type <key_type> | 1797 | %type <key_type> |
417 | 1797 | normal_key_type opt_unique constraint_key_type fulltext spatial | 1798 | normal_key_type opt_unique_combo_clustering constraint_key_type |
418 | 1799 | fulltext spatial unique_opt_clustering unique_combo_clustering unique clustering | ||
419 | 1798 | 1800 | ||
420 | 1799 | %type <key_alg> | 1801 | %type <key_alg> |
421 | 1800 | btree_or_rtree | 1802 | btree_or_rtree |
422 | @@ -2445,7 +2447,7 @@ | |||
423 | 2445 | } | 2447 | } |
424 | 2446 | create_table_set_open_action_and_adjust_tables(lex); | 2448 | create_table_set_open_action_and_adjust_tables(lex); |
425 | 2447 | } | 2449 | } |
427 | 2448 | | CREATE opt_unique INDEX_SYM ident key_alg ON table_ident | 2450 | | CREATE opt_unique_combo_clustering INDEX_SYM ident key_alg ON table_ident |
428 | 2449 | { | 2451 | { |
429 | 2450 | if (add_create_index_prepare(Lex, $7)) | 2452 | if (add_create_index_prepare(Lex, $7)) |
430 | 2451 | MYSQL_YYABORT; | 2453 | MYSQL_YYABORT; |
431 | @@ -6348,6 +6350,13 @@ | |||
432 | 6348 | | opt_constraint constraint_key_type opt_ident key_alg | 6350 | | opt_constraint constraint_key_type opt_ident key_alg |
433 | 6349 | '(' key_list ')' normal_key_options | 6351 | '(' key_list ')' normal_key_options |
434 | 6350 | { | 6352 | { |
435 | 6353 | if (($1.length != 0) | ||
436 | 6354 | && ((enum Key::Keytype)$2 == (Key::CLUSTERING | Key::MULTIPLE))) | ||
437 | 6355 | { | ||
438 | 6356 | /* Forbid "CONSTRAINT c CLUSTERING" */ | ||
439 | 6357 | my_parse_error(ER(ER_SYNTAX_ERROR)); | ||
440 | 6358 | MYSQL_YYABORT; | ||
441 | 6359 | } | ||
442 | 6351 | if (add_create_index (Lex, $2, $3.str ? $3 : $1)) | 6360 | if (add_create_index (Lex, $2, $3.str ? $3 : $1)) |
443 | 6352 | MYSQL_YYABORT; | 6361 | MYSQL_YYABORT; |
444 | 6353 | } | 6362 | } |
445 | @@ -6747,16 +6756,22 @@ | |||
446 | 6747 | lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; | 6756 | lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; |
447 | 6748 | lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; | 6757 | lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; |
448 | 6749 | } | 6758 | } |
450 | 6750 | | UNIQUE_SYM | 6759 | | unique_combo_clustering |
451 | 6751 | { | 6760 | { |
452 | 6752 | LEX *lex=Lex; | 6761 | LEX *lex=Lex; |
454 | 6753 | lex->type|= UNIQUE_FLAG; | 6762 | if ($1 & Key::UNIQUE) |
455 | 6763 | lex->type|= UNIQUE_FLAG; | ||
456 | 6764 | if ($1 & Key::CLUSTERING) | ||
457 | 6765 | lex->type|= CLUSTERING_FLAG; | ||
458 | 6754 | lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; | 6766 | lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; |
459 | 6755 | } | 6767 | } |
461 | 6756 | | UNIQUE_SYM KEY_SYM | 6768 | | unique_combo_clustering KEY_SYM |
462 | 6757 | { | 6769 | { |
463 | 6758 | LEX *lex=Lex; | 6770 | LEX *lex=Lex; |
465 | 6759 | lex->type|= UNIQUE_KEY_FLAG; | 6771 | if ($1 & Key::UNIQUE) |
466 | 6772 | lex->type|= UNIQUE_KEY_FLAG; | ||
467 | 6773 | if ($1 & Key::CLUSTERING) | ||
468 | 6774 | lex->type|= CLUSTERING_FLAG; | ||
469 | 6760 | lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; | 6775 | lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; |
470 | 6761 | } | 6776 | } |
471 | 6762 | | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; } | 6777 | | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; } |
472 | @@ -7139,7 +7154,8 @@ | |||
473 | 7139 | 7154 | ||
474 | 7140 | constraint_key_type: | 7155 | constraint_key_type: |
475 | 7141 | PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } | 7156 | PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } |
477 | 7142 | | UNIQUE_SYM opt_key_or_index { $$= Key::UNIQUE; } | 7157 | | unique_combo_clustering opt_key_or_index { $$= $1; } |
478 | 7158 | |||
479 | 7143 | ; | 7159 | ; |
480 | 7144 | 7160 | ||
481 | 7145 | key_or_index: | 7161 | key_or_index: |
482 | @@ -7158,9 +7174,43 @@ | |||
483 | 7158 | | INDEXES {} | 7174 | | INDEXES {} |
484 | 7159 | ; | 7175 | ; |
485 | 7160 | 7176 | ||
489 | 7161 | opt_unique: | 7177 | opt_unique_combo_clustering: |
490 | 7162 | /* empty */ { $$= Key::MULTIPLE; } | 7178 | /* empty */ { $$= Key::MULTIPLE; } |
491 | 7163 | | UNIQUE_SYM { $$= Key::UNIQUE; } | 7179 | | unique_combo_clustering |
492 | 7180 | ; | ||
493 | 7181 | |||
494 | 7182 | unique_combo_clustering: | ||
495 | 7183 | clustering | ||
496 | 7184 | { | ||
497 | 7185 | $$= (enum Key::Keytype)($1 | Key::MULTIPLE); | ||
498 | 7186 | } | ||
499 | 7187 | | unique_opt_clustering | ||
500 | 7188 | { | ||
501 | 7189 | $$= $1; | ||
502 | 7190 | } | ||
503 | 7191 | ; | ||
504 | 7192 | |||
505 | 7193 | unique_opt_clustering: | ||
506 | 7194 | unique | ||
507 | 7195 | { | ||
508 | 7196 | $$= $1; | ||
509 | 7197 | } | ||
510 | 7198 | | unique clustering | ||
511 | 7199 | { | ||
512 | 7200 | $$= (enum Key::Keytype)($1 | $2); | ||
513 | 7201 | } | ||
514 | 7202 | | clustering unique | ||
515 | 7203 | { | ||
516 | 7204 | $$= (enum Key::Keytype)($1 | $2); | ||
517 | 7205 | } | ||
518 | 7206 | ; | ||
519 | 7207 | |||
520 | 7208 | unique: | ||
521 | 7209 | UNIQUE_SYM { $$= Key::UNIQUE; } | ||
522 | 7210 | ; | ||
523 | 7211 | |||
524 | 7212 | clustering: | ||
525 | 7213 | CLUSTERING_SYM { $$= Key::CLUSTERING; } | ||
526 | 7164 | ; | 7214 | ; |
527 | 7165 | 7215 | ||
528 | 7166 | fulltext: | 7216 | fulltext: |
529 | 7167 | 7217 | ||
530 | === modified file 'sql/table.cc' | |||
531 | --- sql/table.cc 2014-03-17 10:59:40 +0000 | |||
532 | +++ sql/table.cc 2014-03-26 12:37:51 +0000 | |||
533 | @@ -854,11 +854,19 @@ | |||
534 | 854 | KEY_PART_INFO *key_part= &keyinfo->key_part[key_part_n]; | 854 | KEY_PART_INFO *key_part= &keyinfo->key_part[key_part_n]; |
535 | 855 | Field *field= key_part->field; | 855 | Field *field= key_part->field; |
536 | 856 | 856 | ||
538 | 857 | /* Flag field as unique if it is the only keypart in a unique index */ | 857 | /* Flag field as unique and/or clustering if it is the only keypart in a |
539 | 858 | unique/clustering index */ | ||
540 | 858 | if (key_part_n == 0 && key_n != primary_key_n) | 859 | if (key_part_n == 0 && key_n != primary_key_n) |
541 | 860 | { | ||
542 | 859 | field->flags |= (((keyinfo->flags & HA_NOSAME) && | 861 | field->flags |= (((keyinfo->flags & HA_NOSAME) && |
543 | 860 | (keyinfo->user_defined_key_parts == 1)) ? | 862 | (keyinfo->user_defined_key_parts == 1)) ? |
544 | 861 | UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); | 863 | UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); |
545 | 864 | |||
546 | 865 | if (((keyinfo->flags & HA_CLUSTERING) && | ||
547 | 866 | (keyinfo->user_defined_key_parts == 1))) | ||
548 | 867 | field->flags|= CLUSTERING_FLAG; | ||
549 | 868 | } | ||
550 | 869 | |||
551 | 862 | if (key_part_n == 0) | 870 | if (key_part_n == 0) |
552 | 863 | field->key_start.set_bit(key_n); | 871 | field->key_start.set_bit(key_n); |
553 | 864 | if (field->key_length() == key_part->length && | 872 | if (field->key_length() == key_part->length && |
554 | @@ -1133,6 +1141,18 @@ | |||
555 | 1133 | if (new_frm_ver >= 3) | 1141 | if (new_frm_ver >= 3) |
556 | 1134 | { | 1142 | { |
557 | 1135 | keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; | 1143 | keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; |
558 | 1144 | /* Replace HA_FULLTEXT & HA_SPATIAL with HA_CLUSTERING. This way we | ||
559 | 1145 | support TokuDB clustering key definitions without changing the FRM | ||
560 | 1146 | format. */ | ||
561 | 1147 | if (keyinfo->flags & HA_SPATIAL && keyinfo->flags & HA_FULLTEXT) | ||
562 | 1148 | { | ||
563 | 1149 | if (!ha_check_storage_engine_flag(share->db_type(), | ||
564 | 1150 | HTON_SUPPORTS_CLUSTERED_KEYS)) | ||
565 | 1151 | goto err; | ||
566 | 1152 | keyinfo->flags|= HA_CLUSTERING; | ||
567 | 1153 | keyinfo->flags&= ~HA_SPATIAL; | ||
568 | 1154 | keyinfo->flags&= ~HA_FULLTEXT; | ||
569 | 1155 | } | ||
570 | 1136 | keyinfo->key_length= (uint) uint2korr(strpos+2); | 1156 | keyinfo->key_length= (uint) uint2korr(strpos+2); |
571 | 1137 | keyinfo->user_defined_key_parts= (uint) strpos[4]; | 1157 | keyinfo->user_defined_key_parts= (uint) strpos[4]; |
572 | 1138 | keyinfo->algorithm= (enum ha_key_alg) strpos[5]; | 1158 | keyinfo->algorithm= (enum ha_key_alg) strpos[5]; |
573 | 1139 | 1159 | ||
574 | === modified file 'sql/unireg.cc' | |||
575 | --- sql/unireg.cc 2014-02-17 11:12:40 +0000 | |||
576 | +++ sql/unireg.cc 2014-03-26 12:37:51 +0000 | |||
577 | @@ -628,7 +628,15 @@ | |||
578 | 628 | key_parts=0; | 628 | key_parts=0; |
579 | 629 | for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++) | 629 | for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++) |
580 | 630 | { | 630 | { |
582 | 631 | int2store(pos, (key->flags ^ HA_NOSAME)); | 631 | /* Replace HA_CLUSTERING with HA_SPATIAL | HA_FULLTEXT to allow storing |
583 | 632 | TokuDB keys without changing the FRM format. */ | ||
584 | 633 | uint16 key_flags= (uint16)key->flags; | ||
585 | 634 | if (key->flags & HA_CLUSTERING) | ||
586 | 635 | { | ||
587 | 636 | key_flags|= HA_SPATIAL; | ||
588 | 637 | key_flags|= HA_FULLTEXT; | ||
589 | 638 | } | ||
590 | 639 | int2store(pos, (key_flags ^ HA_NOSAME)); | ||
591 | 632 | int2store(pos+2,key->key_length); | 640 | int2store(pos+2,key->key_length); |
592 | 633 | pos[4]= (uchar) key->user_defined_key_parts; | 641 | pos[4]= (uchar) key->user_defined_key_parts; |
593 | 634 | pos[5]= (uchar) key->algorithm; | 642 | pos[5]= (uchar) key->algorithm; |
594 | 635 | 643 | ||
595 | === modified file 'tests/mysql_client_test.c' | |||
596 | --- tests/mysql_client_test.c 2013-08-14 03:57:21 +0000 | |||
597 | +++ tests/mysql_client_test.c 2014-03-26 12:37:51 +0000 | |||
598 | @@ -4676,7 +4676,8 @@ | |||
599 | 4676 | fprintf(stdout, "\n MULTIPLE_KEY_FLAG"); | 4676 | fprintf(stdout, "\n MULTIPLE_KEY_FLAG"); |
600 | 4677 | if (field->flags & AUTO_INCREMENT_FLAG) | 4677 | if (field->flags & AUTO_INCREMENT_FLAG) |
601 | 4678 | fprintf(stdout, "\n AUTO_INCREMENT_FLAG"); | 4678 | fprintf(stdout, "\n AUTO_INCREMENT_FLAG"); |
603 | 4679 | 4679 | if (field->flags & CLUSTERING_FLAG) | |
604 | 4680 | fprintf(stdout, "\n CLUSTERING_FLAG"); | ||
605 | 4680 | } | 4681 | } |
606 | 4681 | } | 4682 | } |
607 | 4682 | mysql_free_result(result); | 4683 | mysql_free_result(result); |
- s/INFORMATION_ SCHEMA. TABLES/ SHOW CREATE TABLE/ in the revision comment
- I don’t think we should allow creation of non-TokuDB tables with
secondary clustering keys. Otherwise once the optimizer support is
reviewed and merged, we will get optimizer making incorrect
assumptions about secondary clustering keys for tables that don’t
actually implement it. On top of that, bad and hard-to-diagnose
things may happen on downgrade or migration to another server flavor;
- I see there’s no support for UNIQUE CLUSTERING KEYs. Let’s fix it if
it’s an oversight, or document if it’s a known limitation?
- any specific reasons to add another reserved keyword to the parser?