MySQL Default Value as Expression is Wrong - mysql

I am running MySQL 8.0.17 and trying to add a default value to a column definition, specifically a JSON column.
create table `test` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `notes` json default ('[]')) default character set utf8mb4 collate 'utf8mb4_unicode_ci'
The query executes fine, but when I look at the table structure the default value is listed as "(_utf8mb4'[]')".
This even happens if I set a default value for a VARCHAR field, but enclose the string in parentheses.
I've also tried using the MySQL JSON_ARRAY() function.
create table `test` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `notes` json default (JSON_ARRAY())) default character set utf8mb4 collate 'utf8mb4_unicode_ci'
but this puts the "(json_array())" as a string as the default.
I feel like I'm doing this write based on the documentation. Is this a bug? or am I missing something?
Thanks!

Related

Cannot create table in MYSQL with UNICODE and INTEGER types, ERROR: 1064

I am trying to create a simple table in mysql but I am getting a syntax error.
Here is the code:
CREATE TABLE survey(
id INTEGER(15) NOT NULL,
`name` UNICODE(65) NOT NULL,
parentId INTEGER(15) NOT NULL,
createdAt TIMESTAMP(30) NOT NULL,
modifiedAt TIMESTAMP (30) NOT NULL,
surveyUrl UNICODE(100) NOT NULL,
PRIMARY KEY(id)
);
I have tried changing the UNICODE to STRING and placing the column names between marks with no luck. Thank you!
a Datatype UNICOde and the prcision 30 for timestampo are not allowed.
You can switch to following format, iff you need another character set and collation besides the default
More about collations
CREATE TABLE survey(
id BIGINT NOT NULL,
`name` varchar(65) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
parentId BIGINT NOT NULL,
createdAt TIMESTAMP(6) NOT NULL,
modifiedAt TIMESTAMP (6) NOT NULL,
surveyUrl varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY(id)
);

Why this IF NOT EXISTS statement is not ok?

I'm trying to create a table but it keeps giving me error and I'm not able to figure out the problem even after checking the manual
That's the code:
CREATE TABLE IF NOT EXISTS table1
(ID BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_cI NOT NULL,
VALUE INT(11) NOT NULL,
ATTACHMENT TEXT NULL DEFAULT NULL)
I solved by using a different word from VALUE. It is already defined as keyword

mysql workbench converts the nvarchar columns to varchar?

I have defined my tables as follows;
CREATE TABLE IF NOT EXISTS test.notes ( id INT(10)
UNSIGNED NOT NULL AUTO_INCREMENT, clientid INT(10) NOT NULL,
userid INT(10) NOT NULL,
notes NVARCHAR(256) NULL DEFAULT NULL, createddatetime TIMESTAMP
NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id)) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;
here the notes column i defined as navarchar, but finally it turns as varchar column. Im using 6.3 version . What is wrong here?
From the MySQL documentation, we can see that internally MySQL will just map NVARCHAR to VARCHAR with a UTF-8 character set. The documentation mentions that the following definitions are all equivalent:
VARCHAR(10) CHARACTER SET utf8
NATIONAL VARCHAR(10)
NVARCHAR(10)
NCHAR VARCHAR(10)
NATIONAL CHARACTER VARYING(10)
NATIONAL CHAR VARYING(10)

MySQL alter table gives unknown column error

I'm renaming a bunch of columns in a lot of my tables and changing their data types for a major system update, and I haven't had many issues except for this one.
Error Code: 1054. Unknown column 'FactoryID' in 'factories'
show create table `factories`;
CREATE TABLE `factories` (
`FactoryID` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`ParentFactoryID` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`Name` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`Notes` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`DateTimeAdded` datetime DEFAULT NULL,
`CountryID` smallint(5) unsigned NOT NULL,
`ListID` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`Deleted` int(1) DEFAULT '0',
PRIMARY KEY (`FactoryID`),
UNIQUE KEY `FactoryID` (`FactoryID`),
KEY `ParentFactoryID` (`ParentFactoryID`),
KEY `CountryID` (`CountryID`),
CONSTRAINT `factories[CountryID]` FOREIGN KEY (`CountryID`) REFERENCES `countries` (`CountryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `sterling`.`factories`
CHANGE COLUMN `CountryID` `CountryID` SMALLINT(5) UNSIGNED NOT NULL AFTER `FactoryID`,
CHANGE COLUMN `ParentFactoryID` `_OriginalFactoryID` CHAR(36) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci' NULL DEFAULT NULL AFTER `ListID`,
CHANGE COLUMN `DateTimeAdded` `__Added` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) AFTER `__Active`,
CHANGE COLUMN `Deleted` `__Active` TINYINT(1) NOT NULL DEFAULT 1 ,
ADD COLUMN `__Updated` TIMESTAMP(6) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6) AFTER `__Added`,
drop primary key,
change column`FactoryID` `#FactoryID`char(36)null after`__Updated`,
add column`FactoryID`binary(8)not null first,
add index`#FactoryID`(`#FactoryID`);
Am I missing an order of operations sort of thing? If all of those changes happen in order, I'm not sure what exactly the problem is, since at no time that FactoryID is referenced does it not exist.
The columnname that after refers to is supposed to be the new name of the column in the final table. It doesn't matter where in the statement you change the name.
And it actually even makes this following statement fail:
alter table tablename
add column b int after a,
drop column a
Error Code: 1054. Unknown column 'a' in 'tablename'
as in the final table, there will be no column a anymore, so it is invalid even if you drop a only after you already added column b.
In your case, you would need to change
CHANGE COLUMN `CountryID` `CountryID` ... AFTER `FactoryID`,
to
CHANGE COLUMN `CountryID` `CountryID` ... AFTER `#FactoryID`,
in order to anticipate that you will (later) rename the column FactoryID to #FactoryID.
To make it complete: in after, you cannot refer to a column that you will add later. For example, in the end of your statement, you actually add another column FactoryID, but you cannot yet refer to it here (otherwise, the query would not have failed). You could add that column first though (and even before you rename the original FactoryId, MySQL allows you to swap columnnames that way). CHANGE COLUMN CountryID CountryID ... AFTER FactoryID would then work, but would refer to the new column (so in total, CountryID would be the 2nd column, which may or may not be what you intended).
I don't know if it is officially documented somewhere, you will probably have to take it as convention, but it has "always" been that way.

MySQL castr operator

Is there any shorter equivalent for the following query: (I can not alter the table). Are cast operators applicable here?
select convert(old_text using utf8) as text,
convert(rev_timestamp using utf8) as ts,
convert(rev_user_text using utf8) as user from revision;
Update: The table schema is:
CREATE TABLE `revision` (
`rev_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`rev_page` INT(10) UNSIGNED NOT NULL,
`rev_text_id` INT(10) UNSIGNED NOT NULL,
`rev_comment` TINYBLOB NOT NULL,
`rev_user` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`rev_user_text` VARCHAR(255) NOT NULL DEFAULT '' COLLATE 'latin1_bin',
`rev_timestamp` BINARY(14) NOT NULL DEFAULT '\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0',
`old_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`old_text` MEDIUMBLOB NOT NULL,
`old_flags` TINYBLOB NOT NULL,
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
the best is to alter your table and set utf8 for your needed columns instead of everytime converting them
ALTER TABLE t MODIFY old_text CHAR(50) CHARACTER SET utf8;
ALTER TABLE t MODIFY rev_timestamp CHAR(50) CHARACTER SET utf8;
ALTER TABLE t MODIFY rev_user_text CHAR(50) CHARACTER SET utf8;
and then select them normal.
select old_text as text, rev_timestamp as ts, rev_user_text as user
from revision;
note: about char(50) change it to your needs.
set names utf8;
SELECT old_text AS text, rev_timestamp AS ts, rev_user_text AS user
FROM revisions;
...but this will break if you are sending DML in a different character set.
The easiest way to modify, is to modify the my.ini file in mysql character set key,
default-character-set = utf8
character_set_server = utf8
After modification, restart the mysql service, service mysql restart