Bug #18644 Documentation Errors for Create Table syntax
Submitted: 30 Mar 2006 10:00 Modified: 26 May 2006 20:41
Reporter: Keith Roberts Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Documentation Severity:S2 (Serious)
Version:5.0.18 OS:Linux (SuSE linux 9.2 pro)
Assigned to: Paul DuBois CPU Architecture:Any

[30 Mar 2006 10:00] Keith Roberts
Description:
MySQL Manual ref: 2006-01-28 (revision: 1077)

Hi all.

I'm using mysql 5.0.18-standard-log and getting my head
around the mysql manual, and I note that the create table
syntax is not correct.

There are quite a few places where the syntax in this
section does not actually reflect the syntax mysql uses,
according to the conventions noted in the manual.

As the mysql manual is the canonical reference on mysql and it's syntax,
I think it is very important that the mysql syntax documented in the
manual is correct and up to date for the actual implementation of mysql.

<Quote>
1.2. Conventions Used in This Manual

In syntax descriptions, square brackets ( [ and ] ) indicate
optional words or clauses. For example, in the following
statement, IF EXISTS is optional:

DROP TABLE [IF EXISTS] tbl_name

When a syntax element consists of a number of alternatives,
the alternatives are separated by vertical bars (|).

When one member from a set of choices *may* be chosen, the
alternatives are listed within square brackets ( [ and ] ):

TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)

When one member from a set of choices *must* be chosen, the
alternatives are listed within braces ( { and } ):

{DESCRIBE | DESC} tbl_name [col_name | wild]

An ellipsis (...) indicates the omission of a section of a
statement, typically to provide a shorter version of more
complex syntax. For example, INSERT ... SELECT is shorthand
for the form of INSERT statement that is followed by a
SELECT statement.

An ellipsis can also indicate that the preceding syntax
element of a statement may be repeated. In the following
example, multiple reset_option values may be given, with
each of those after the first preceded by commas:

RESET reset_option [,reset_option] ...
</Quote>

Bearing in mind the above manual syntax conventions, and
looking at the create table syntax, we have:

(Copied and pasted directly from the docs)

13.1.5. CREATE TABLE Syntax

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    [(create_definition,...)]
    [table_options] [select_statement]

So if I read the syntax above correctly, according to the manual conventions,
the above syntax tells me that the following is legal:

mysql> create table t1;
ERROR 1113 (42000): A table must have at least 1 column

So surely the create_definition is required, and must not be
enclosed in [] brackets, indicating that it is optional?

create_definition:
    column_definition
  | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
  | KEY [index_name] [index_type] (index_col_name,...)
  | INDEX [index_name] [index_type] (index_col_name,...)
  | [CONSTRAINT [symbol]] UNIQUE [INDEX]
        [index_name] [index_type] (index_col_name,...)
  | [FULLTEXT|SPATIAL] [INDEX] [index_name] (index_col_name,...)

again the above line says that FULLTEXT or SPATIAL are
optional choices, so if I do:

mysql> create table t1 (
    -> a text,
    -> (a)
    -> );
ERROR 1064 (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 '(a)
)' at line 3

I get an error.

If I do:

mysql> create table t1 (
    -> a text,
    -> fulltext (a)
    -> );
Query OK, 0 rows affected (0.04 sec)

There is no error.

So the [FULLTEXT | SPATIAL] is not an optional choice, but a
required choice, and should be enclosed in {} brackets to
indicate this, such as {FULLTEXT|SPATIAL}.

column_definition:
    col_name type [NOT NULL | NULL] [DEFAULT default_value]
        [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
        [COMMENT 'string'] [reference_definition]

type:
    TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  | INT[(length)] [UNSIGNED] [ZEROFILL]
  | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  | BIGINT[(length)] [UNSIGNED] [ZEROFILL]
  | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
  | DATE
  | TIME
  | TIMESTAMP
  | DATETIME
  | YEAR
  | CHAR(length) [BINARY | ASCII | UNICODE]
  | VARCHAR(length) [BINARY]
  | BINARY(length)
  | VARBINARY(length)
  | TINYBLOB
  | BLOB
  | MEDIUMBLOB
  | LONGBLOB
  | TINYTEXT [BINARY]
  | TEXT [BINARY]
  | MEDIUMTEXT [BINARY]
  | LONGTEXT [BINARY]
  | ENUM(value1,value2,value3,...)
  | SET(value1,value2,value3,...)
  | spatial_type

According to the column_definition syntax above, I should be
able to use any type from the type list, and suffix it with
auto_increment.

So if I do:

mysql> create table t1 (
    -> a_date date not null auto_increment
    -> );
ERROR 1063 (42000): Incorrect column specifier for column
'a_date'

Obviously, you cannot auto_increment a date column, but the
docs say that you can!

I would like to suggest that the CREATE TABLE column_definition is
re-written with several sub-types that would list the correct optional
(or required) clauses/attributes for each of those sub-types, such as:

column_definition:
    col_name int_type [NOT NULL | NULL] [DEFAULT default_value]
      [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
      [COMMENT 'string'] [reference_definition]

  | col_name real_type [NOT NULL | NULL] [DEFAULT default_value]
      [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
      [COMMENT 'string'] [reference_definition]

  | col_name date_type [NOT NULL | NULL] [DEFAULT default_value]
        [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string'] [reference_definit
ion]

  | col_name char_type [NOT NULL | NULL] [DEFAULT default_value]
        [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
        [COMMENT 'string'] [reference_definition]

  | col_name text_type [NOT NULL | NULL] [DEFAULT default_value]
        [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
        [COMMENT 'string'] [reference_definition]

  | col_name set_type [NOT NULL | NULL] [DEFAULT default_value]
        [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
        [COMMENT 'string'] [reference_definition]

int_type:
    TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  | INT[(length)] [UNSIGNED] [ZEROFILL]
  | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  | BIGINT[(length)] [UNSIGNED] [ZEROFILL]

real_type
  | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]

date_type
  | DATE
  | TIME
  | TIMESTAMP
  | DATETIME
  | YEAR

char_type
  | CHAR(length) [BINARY | ASCII | UNICODE]
  | VARCHAR(length) [BINARY]
  | BINARY(length)
  | VARBINARY(length)

text_type
  | TINYBLOB
  | BLOB
  | MEDIUMBLOB
  | LONGBLOB
  | TINYTEXT [BINARY]
  | TEXT [BINARY]
  | MEDIUMTEXT [BINARY]
  | LONGTEXT [BINARY]

set_type
  | ENUM(value1,value2,value3,...)
  | SET(value1,value2,value3,...)
  | spatial_type

I have not changed the clauses/attributes for each sub-type
column_definition option above, apart from removing the [AUTO_INCREMENT]
attribute from the date_type option.

I need to get my head around and fully understand:

11. Data Types
13. SQL Statement Syntax

From the manual first.

Hopefully, if the documentation for mysql syntax is 100% correct, this will
give mysql users a quick overview of all mysql syntax available, and reduce the need
for further text discussions on what is, or is not, legal mysql syntax.

Kind Regards

Keith Roberts

In theory, theory and practice are the same;
in practice they are not.

How to repeat:
Please see the relevant section of the manual - 13.1.5. CREATE TABLE Syntax

Suggested fix:
re-write the relevant section so it matches the mysql syntax correctly.
[30 Mar 2006 10:44] Valeriy Kravchuk
Thank you for a problem report. Yes, this page, http://dev.mysql.com/doc/refman/5.0/en/create-table.html (and, maybe, others), have to present formal syntax in a more correct and strict way. If correct formal syntax is too large to represent in the manual, some less formal descriptions may be useful (like "table should have at least one column" etc.).

So, it looks like a reasonable deocumentation request for me.
[30 Mar 2006 12:26] Keith Roberts
I think it would help to have the full formal syntax, even if it has to be spread over several pages.

The syntax diagrams should show mysql users at a glance the correct syntax, and all available options for a specific construct.
[26 May 2006 20:41] Paul DuBois
Thank you for your bug report. This issue has been addressed in the
documentation. The updated documentation will appear on our website
shortly, and will be included in the next release of the relevant
product(s).

Additional info:

Thanks for your comments. I've made a number of the changes
that you suggested. I did not make the suggested change regarding
data types.  Instead, I updated the attributes for the string types,
which were outdates, and added a paragraph to the text following
the syntax to point out that AUTO_INCREMENT applies only to integer
types, and that DEFAULT doesn't apply to the BLOB/TEXT types. I
found this less unwieldly than "unpacking" all the data type descriptions
in the manner you proposed.