Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do integer DEFAULT values get quotes?

Simple test table, created on MySQL 5.6.23:

CREATE TABLE `test` (
  `tinyint` tinyint(1) NOT NULL DEFAULT 0,
  `int` int(11) NOT NULL DEFAULT 0
);

Note how the DEFAULT values are written: literally 0. As soon as it's created, I do:

SHOW CREATE TABLE `test`;

and get:

CREATE TABLE `test` (
  `tinyint` tinyint(1) NOT NULL DEFAULT '0',
  `int` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1

The DEFAULT values have gained quotes: '0'!

Why does that happen? More importantly, was I supposed to be surrounding numeric default values with quotes this whole time?

like image 550
smitelli Avatar asked Feb 18 '16 19:02

smitelli


People also ask

What is the default value of Number data type?

For numeric types, the default is 0 , with the exception that for integer or floating-point types declared with the AUTO_INCREMENT attribute, the default is the next value in the sequence. For date and time types other than TIMESTAMP , the default is the appropriate “zero” value for the type.

Why are DEFAULT values used?

Default values are very often used as an aid to data entry. If we can provide data to users that is most often the data that they would have entered, then we would have done them a favor and sped up data entry.

How do I set default value?

Set a default value Select the field that you want to change. On the General tab, type a value in the Default Value property box. The value you that you can enter depends on the data type that is set for the field. For example, you can type =Date() to insert the current date in a Date/Time field.

Why would you use DEFAULT values in columns?

A default value makes it a lot easier to insert new rows into a table - all columns with a default value do not need to be explicitly specified and provided with a value in the INSERT statement, if that default value is OK (like getdate() for a "LastChangeOn" date column).


2 Answers

Of course, SHOW CREATE TABLE does not retrieve the original CREATE TABLE code. Even if it was actually stored somewhere, it wouldn't necessarily reflect the current table definition (you can ALTER TABLE afterwards as much as you want). That code needs to be recreated on demand. MySQL Server is mostly written in C with some bits of C++. I can't tell it for sure (I'm just speculating because I know very little C and I'm not familiar with MySQL codebase) but the function that does so could be this:

int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
                      HA_CREATE_INFO *create_info_arg, bool show_database)

... which calls this other one:

static bool print_default_clause(THD *thd, Field *field, String *def_value,
                                 bool quoted)

If you check the source code you'll realise it's a long tedious string concatenation that spans across hundreds of lines. (C is lightning fast because it's closer to the machine than modern high level languages, but that comes at the price of being less suitable for quick development.)

There's no need to quote a number. But whoever wrote this code generator years ago didn't care about this detail. And MySQL will just cast strings to numbers automatically whenever it needs to do so, with better or worse results:

mysql> SELECT 1+99, '1'+99, '1x' + '99x', '1' + 'x99';
+------+--------+--------------+-------------+
| 1+99 | '1'+99 | '1x' + '99x' | '1' + 'x99' |
+------+--------+--------------+-------------+
|  100 |    100 |          100 |           1 |
+------+--------+--------------+-------------+
1 row in set, 3 warnings (0.00 sec)

mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '99x' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '1x'  |
| Warning | 1292 | Truncated incorrect DOUBLE value: 'x99' |
+---------+------+-----------------------------------------+
3 rows in set (0.00 sec)

Since the quoted number comes from the actual default value of an actual column, it's never going to be an invalid number (you couldn't have created the table otherwise). So it's not a big deal.

To sum up: that code is just a template someone wrote years ago, it's not meant to be a style guide or a coding standard.

like image 76
Álvaro González Avatar answered Oct 24 '22 00:10

Álvaro González


It's likely just the way the SHOW CREATE TABLE syntax is using it. I was able to submit it using both methods and it worked for me.

/*[2:40:11 PM][16 ms]*/ CREATE TABLE `test` ( `tinyint` TINYINT(1) NOT NULL DEFAULT 0, `int` INT(11) NOT NULL DEFAULT 0 ) ENGINE=INNODB DEFAULT CHARSET=latin1; 
/*[2:40:22 PM][30 ms]*/ CREATE TABLE `test2` ( `tinyint` TINYINT(1) NOT NULL DEFAULT '0', `int` INT(11) NOT NULL DEFAULT '0' ) ENGINE=INNODB DEFAULT CHARSET=latin1; 
like image 33
cngodles Avatar answered Oct 24 '22 00:10

cngodles