Skip to content
/ server Public
Open
2 changes: 2 additions & 0 deletions mysql-test/main/varchar_no_length.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Use default conf to set collation and charset
!include include/default_my.cnf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like a junk config

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only used it to set a default charset/collation to have consistency for the tests.
If the default charset/collation changes in the future, this may cause this test to fail, even when the logic is still correct (maybe it's better to have it fail and the dev should verify anyway?).
Also, I wasn't sure if the server's choice for the default charset changes based on the machine settings (such as language), in that case the test my fail for other machines, so I thought having it set in the .opt is better.
What do you think?

49 changes: 49 additions & 0 deletions mysql-test/main/varchar_no_length.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#
# SQL Standard T081: VARCHAR without explicit length specification
#
#
# Basic test: CREATE TABLE with VARCHAR without length
#
CREATE TABLE t1 (a VARCHAR);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(16383) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DESC t1;
Field Type Null Key Default Extra
a varchar(16383) YES NULL
# Verify we can insert and retrieve data
INSERT INTO t1 VALUES ('test string');
INSERT INTO t1 VALUES ('');
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1;
a
test string

NULL
DROP TABLE t1;
#
# Test VARCHAR without length with various character sets
#
CREATE TABLE t1 (a VARCHAR CHARSET utf8mb4);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(16383) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR CHARSET latin1);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(65532) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR) CHARSET latin1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(65532) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1;
45 changes: 45 additions & 0 deletions mysql-test/main/varchar_no_length.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#
# Test for SQL Standard T081: "Optional string types maximum length"
# This tests the feature that allows VARCHAR columns to be created without
# specifying a length, defaulting to the maximum VARCHAR length (65535)
#

--echo #
--echo # SQL Standard T081: VARCHAR without explicit length specification
--echo #

--echo #
--echo # Basic test: CREATE TABLE with VARCHAR without length or charset
--echo #

CREATE TABLE t1 (a VARCHAR);
SHOW CREATE TABLE t1;
DESC t1;

--echo # Verify we can insert and retrieve data
INSERT INTO t1 VALUES ('test string');
INSERT INTO t1 VALUES ('');
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1;

DROP TABLE t1;

--echo #
--echo # Test VARCHAR without length with various column charsets
--echo #

CREATE TABLE t1 (a VARCHAR CHARSET utf8mb4);
SHOW CREATE TABLE t1;
DROP TABLE t1;

CREATE TABLE t1 (a VARCHAR CHARSET latin1);
SHOW CREATE TABLE t1;
DROP TABLE t1;

--echo #
--echo # Basic test: CREATE TABLE with charset
--echo #

CREATE TABLE t1 (a VARCHAR) CHARSET latin1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
10 changes: 9 additions & 1 deletion sql/sql_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2862,8 +2862,16 @@ Type_handler_varchar::Column_definition_set_attributes(
}
break;
case COLUMN_DEFINITION_ROUTINE_LOCAL:
case COLUMN_DEFINITION_TABLE_FIELD:
break;
case COLUMN_DEFINITION_TABLE_FIELD:
/*
Support SQL Standard T081: "Optional string types maximum length"
Allows users to specify VARCHAR fields without a length
*/
def->length = def->charset && def->charset->mbmaxlen ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we won't be able to determine the length correctly here. I think you'll realize that as soon as you'll get to trying the tests I requested above.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I am only considering column and DB charsets, I should also consider the table charset.

So the order is column > table > DB
Is it possible DB charset is not set? In that case I can consider session charset and system-wide charsets as fallback, would that be necessary?

MAX_FIELD_VARCHARLENGTH / def->charset->mbmaxlen :
MAX_FIELD_VARCHARLENGTH / thd->db_charset->mbmaxlen;
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is likely correct though.

}
thd->parse_error();
return true;
Expand Down