vitessio / vitess

Vitess is a database clustering system for horizontal scaling of MySQL.
http://vitess.io
Apache License 2.0
18.6k stars 2.1k forks source link

Non-1st TIMESTAMP column clause in CREATE TABLE statement fails #6329

Open shlomi-noach opened 4 years ago

shlomi-noach commented 4 years ago

When filing a bug, please include the following headings if possible. Any example text in this template can be deleted.

Overview of the Issue

A CREATE TABLE statement, which is accepted by MySQL as valid, is not accepted by Vitess. The problem is with a TIMESTAMP column -- which not the 1st in the table (1st TIMESTAMP column is special because it defaults CURRENT_TIMESTAMP if no directive is given).

For 2nd TIMESTAMP column, if no DEFAULT directive or DEFAULT value are given, the implicit behavior is that the colunm is NULL-able and defaults NULL. That's how MySQL interprets it. But vitess errors out.

Reproduction Steps

  1. Attempt to deploy the following schema:
CREATE TABLE IF NOT EXISTS database_instance_downtime (
  hostname varchar(128) NOT NULL,
  port smallint(5) unsigned NOT NULL,
  downtime_active tinyint(4) DEFAULT NULL,
  begin_timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
  end_timestamp timestamp,
  owner varchar(128) CHARACTER SET utf8 NOT NULL,
  reason text CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (hostname, port)
) ENGINE=InnoDB DEFAULT CHARSET=ascii

(actual table extracted from orchestrator)

Vitess errors with:

Error 1067: vtgate: http://shlomidev-local-localminikube1a1-vtgate-52ac2681-9dbd9b7b6k8tk7:15000/: target: simple.-.master, used tablet: localminikube1a1-2388979711 (172.17.0.4): vttablet: rpc error: code = InvalidArgument desc = Invalid default value for 'end_timestamp' (errno 1067) (sqlstate 42000) (CallerID: shlomi): Sql: "CREATE TABLE IF NOT EXISTS database_instance_downtime (\n\t\t\thostname varchar(128) NOT NULL,\n\t\t\tport smallint(5) unsigned NOT NULL,\n\t\t\tdowntime_active tinyint(4) DEFAULT NULL,\n\t\t\tbegin_timestamp timestamp DEFAULT CURRENT_TIMESTAMP,\n\t\t\tend_timestamp timestamp,\n\t\t\towner varchar(128) CHARACTER SET utf8 NOT NULL,\n\t\t\treason text CHARACTER SET utf8 NOT NULL,\n\t\t\tPRIMARY KEY (hostname, port)\n\t\t) ENGINE=InnoDB DEFAULT CHARSET=ascii", BindVars: {}; query=
        CREATE TABLE IF NOT EXISTS database_instance_downtime (
            hostname varchar(128) NOT NULL,
            port smallint(5) unsigned NOT NULL,
            downtime_active tinyint(4) DEFAULT NULL,
            begin_timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
            end_timestamp timestamp,
            owner varchar(128) CHARACTER SET utf8 NOT NULL,
            reason text CHARACTER SET utf8 NOT NULL,
            PRIMARY KEY (hostname, port)
        ) ENGINE=InnoDB DEFAULT CHARSET=ascii

Note Invalid default value for 'end_timestamp' (errno 1067) (sqlstate 42000)

The above table definition is equivalent to the following:

CREATE TABLE IF NOT EXISTS database_instance_downtime (
  hostname varchar(128) NOT NULL,
  port smallint(5) unsigned NOT NULL,
  downtime_active tinyint(4) DEFAULT NULL,
  begin_timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
  end_timestamp timestamp NULL DEFAULT NULL,
  owner varchar(128) CHARACTER SET utf8 NOT NULL,
  reason text CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (hostname, port)
) ENGINE=InnoDB DEFAULT CHARSET=ascii

Notice end_timestamp timestamp NULL DEFAULT NULL

The latter is accepted by vitess. Vitess should support the former variation as well.

Operating system and Environment details

Any.

mcronce commented 3 years ago

I think this is the same issue we're seeing with a PHP Laravel test. The following CREATE TABLE (output of SHOW CREATE TABLE from vanilla MySQL, but same result from the actual CREATE TABLE) fails:

CREATE TABLE `users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email_verified_at` timestamp NULL DEFAULT NULL,
  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

The error is:

ERROR 1067 (42000): vtgate: http://6fec745a2fd3:33574/: target: test.0.master, used tablet: test-1 (): vttablet: rpc error: code = InvalidArgument desc = Invalid default value for 'email_verified_at' (errno 1067) (sqlstate 42000) (CallerID: userData1): Sql: "create table users (\n\tid bigint(20) unsigned not null auto_increment,\n\t`name` varchar(255) collate utf8mb4_unicode_ci not null,\n\temail varchar(255) collate utf8mb4_unicode_ci not null,\n\temail_verified_at timestamp default null,\n\t`password` varchar(255) collate u