Posted by Craige McWhirter on
Last edited

I encountered this gem of an error working with MySQL today:

ERROR 1136 (21S01) at line 144: Column count doesn't match value count at row 1

TL;DR

A mismatch between the number of destination columns and the number of columns specified in your MySQL script will generate this error.

In Detail

I was converting the database for one application (Storyboard) to another (Phabricator]. Something I've not done before and the code was more than six months old and a hand me down from a previous dev. It worked then but the SQL schema for both has changed since then.

This is the code snippet it choked on:

insert into user
   select
     id,
     phid,
     username,
     if(full_name is NULL, username, full_name),
     NULL,
     NULL,
   storyboard.make_cert(32),
   '',
    unix_timestamp(created_at),
    if(updated_at is NULL, unix_timestamp(now()), unix_timestamp(updated_at)),
    NULL, 0, 0, '', storyboard.make_cert(255),
    0, 0, is_superuser, 'UTC', 1, 1,
    storyboard.make_cert(64),
    0
   from storyboard.users;

It turns out that this error is telling me that the destination table (phabricator_users.user) does not have the same number of columns as the select statement from storyboard.users.

Examining storyboard.users first, I found this:

mysql> desc users;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| created_at   | datetime     | YES  |     | NULL    |                |
| updated_at   | datetime     | YES  |     | NULL    |                |
| email        | varchar(255) | YES  | UNI | NULL    |                |
| is_staff     | tinyint(1)   | YES  |     | NULL    |                |
| is_active    | tinyint(1)   | YES  |     | NULL    |                |
| is_superuser | tinyint(1)   | YES  |     | NULL    |                |
| last_login   | datetime     | YES  |     | NULL    |                |
| openid       | varchar(255) | YES  |     | NULL    |                |
| full_name    | varchar(255) | YES  | MUL | NULL    |                |
| enable_login | tinyint(1)   | NO   |     | 1       |                |
+--------------+--------------+------+-----+---------+----------------+
11 rows in set (0.00 sec)

Examining phabricator_users.user I found this:

mysql> desc user;
+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| id                 | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| phid               | varchar(64)      | NO   | UNI | NULL    |                |
| userName           | varchar(64)      | NO   | UNI | NULL    |                |
| realName           | varchar(128)     | NO   | MUL | NULL    |                |
| sex                | char(1)          | YES  |     | NULL    |                |
| translation        | varchar(64)      | YES  |     | NULL    |                |
| passwordSalt       | varchar(32)      | YES  |     | NULL    |                |
| passwordHash       | varchar(32)      | YES  |     | NULL    |                |
| dateCreated        | int(10) unsigned | NO   |     | NULL    |                |
| dateModified       | int(10) unsigned | NO   |     | NULL    |                |
| profileImagePHID   | varchar(64)      | YES  |     | NULL    |                |
| consoleEnabled     | tinyint(1)       | NO   |     | NULL    |                |
| consoleVisible     | tinyint(1)       | NO   |     | NULL    |                |
| consoleTab         | varchar(64)      | NO   |     | NULL    |                |
| conduitCertificate | varchar(255)     | NO   |     | NULL    |                |
| isSystemAgent      | tinyint(1)       | NO   |     | 0       |                |
| isDisabled         | tinyint(1)       | NO   |     | NULL    |                |
| isAdmin            | tinyint(1)       | NO   |     | NULL    |                |
| timezoneIdentifier | varchar(255)     | NO   |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+

phabricator_users.user has 19 columns, yet the original MySQL syntax has 24 columns listed. So there's been a schema change in the intervening 6+ months since the script was last run.

Identifying missing fields and removing surplus columns from the script resulted in this version of the stanza:

insert into user
   select
     id,
     phid,
     email,
     if(full_name is NULL, email, full_name),
     NULL,
     NULL,
     storyboard.make_cert(32),
     '',
     unix_timestamp(created_at),
     if(updated_at is NULL, unix_timestamp(now()), unix_timestamp(updated_at)),
     NULL, 0, 0, '', storyboard.make_cert(255),
     0, 0, is_superuser, 'UTC'
   from storyboard.users;

... which unsurprisingly now worked.