Since MySQL 8.0.23 we’ve had the ability to create invisible columns, which are columns that are normally hidden to queries (but can easily be accessed if required).
With the introduction of invisible columns comes the inevitable requirement to check a table to see if it contains any invisible columns.
Fortunately there are many ways we can do this. Below are five ways to check a table for invisible columns.
The DESCRIBE
Statement
One way to check a table for invisible columns is with the DESCRIBE
statement:
DESCRIBE t1;
Sample result:
+-------+-------------+------+-----+---------+-----------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-----------+ | c1 | varchar(20) | YES | | NULL | | | c2 | varchar(20) | YES | | NULL | | | c3 | varchar(20) | YES | | Salad | INVISIBLE | +-------+-------------+------+-----+---------+-----------+
The DESCRIBE
command returns information about table structure, including columns and their data types, along with an Extra
column that contains INVISIBLE
if the column is invisible.
In the above example I checked a table called t1
, which contains one invisible column called c3
.
I should mention that the Extra
column isn’t used solely for invisible columns. It can contain other data too. For example if it’s a generated column, then it would contain information that tells us that. So if the above invisible column was also generated, we might see something like this:
+-------+-------------+------+-----+---------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-----------------------------+ | c1 | varchar(20) | YES | | NULL | | | c2 | varchar(20) | YES | | NULL | | | c3 | varchar(20) | YES | | NULL | VIRTUAL GENERATED INVISIBLE | +-------+-------------+------+-----+---------+-----------------------------+
We can actually follow up the table name with a column name if required. This allows us to narrow it down to just one specific column:
DESCRIBE t1 c3;
Sample result:
+-------+------+------+-----+---------+-----------+ | Field | Type | Null | Key | Default | Extra | +-------+------+------+-----+---------+-----------+ | c3 | int | YES | | NULL | INVISIBLE | +-------+------+------+-----+---------+-----------+
The DESC
Statement
We can shorten the above statement even further by using DESC
instead of DESCRIBE
:
DESC t1;
Sample result:
+-------+-------------+------+-----+---------+-----------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-----------+ | c1 | varchar(20) | YES | | NULL | | | c2 | varchar(20) | YES | | NULL | | | c3 | varchar(20) | YES | | Salad | INVISIBLE | +-------+-------------+------+-----+---------+-----------+
DESC
does exactly the same thing as DESCRIBE
, as seen in this example.
The EXPLAIN
Statement
EXPLAIN
and DESCRIBE
are synonyms, so we can alternatively use EXPLAIN
instead of DESCRIBE
or DESC
:
EXPLAIN t1;
Sample result:
+-------+-------------+------+-----+---------+-----------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-----------+ | c1 | varchar(20) | YES | | NULL | | | c2 | varchar(20) | YES | | NULL | | | c3 | varchar(20) | YES | | Salad | INVISIBLE | +-------+-------------+------+-----+---------+-----------+
So we can see that the same result was returned as in the previous examples.
The SHOW COLUMNS
Statement
DESCRIBE
(and its synonyms) is actually a shortcut for the SHOW COLUMNS
statement. So we can use the SHOW COLUMNS
statement to get the same result that we got in the previous examples:
SHOW COLUMNS FROM t1;
Sample result:
+-------+-------------+------+-----+---------+-----------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-----------+ | c1 | varchar(20) | YES | | NULL | | | c2 | varchar(20) | YES | | NULL | | | c3 | varchar(20) | YES | | Salad | INVISIBLE | +-------+-------------+------+-----+---------+-----------+
The SHOW COLUMNS
statement also allows us to filter the results, and even show extended info:
SHOW EXTENDED FULL COLUMNS FROM t1
LIKE 'c3';
Sample result:
+-------+-------------+--------------------+------+-----+---------+-----------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-------+-------------+--------------------+------+-----+---------+-----------+---------------------------------+---------+ | c3 | varchar(20) | utf8mb4_0900_ai_ci | YES | | Salad | INVISIBLE | select,insert,update,references | | +-------+-------------+--------------------+------+-----+---------+-----------+---------------------------------+---------+
We can also return only invisible columns by using a query like this:
SHOW COLUMNS FROM t1
WHERE Extra LIKE '%invisible%';
Sample result:
+-------+-------------+------+-----+---------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-----------------------------+ | c3 | varchar(20) | YES | | NULL | VIRTUAL GENERATED INVISIBLE | +-------+-------------+------+-----+---------+-----------------------------+
In this example the column was also generated. This is why I used the LIKE
operator instead of the equals operator (=
).
The COLUMNS
Information Schema Table
The information_schema.columns
table contains information about columns in each table on the server. It includes a column called EXTRA
that will tell us if a column is invisible. So we can query this table to check a table for invisible columns:
SELECT
column_name,
extra
FROM information_schema.columns
WHERE table_schema = 'KrankyKranes'
AND table_name = 't1';
Result:
+-------------+-----------+ | COLUMN_NAME | EXTRA | +-------------+-----------+ | c1 | | | c2 | | | c3 | INVISIBLE | +-------------+-----------+
One advantage of the information_schema.columns
table is that we could run a query that returns all invisible columns in the database or even all invisible columns on the server.
To do this, all we need to do is change our WHERE
clause to something like this:
SELECT
table_schema,
table_name,
column_name,
data_type,
extra
FROM information_schema.columns
WHERE extra LIKE '%invisible%';
Sample result:
+--------------+------------+-------------+-----------+-----------------------------+ | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | DATA_TYPE | EXTRA | +--------------+------------+-------------+-----------+-----------------------------+ | krankykranes | t2 | c3 | varchar | INVISIBLE | | krankykranes | t5 | c3 | varchar | INVISIBLE | | krankykranes | t1 | c3 | varchar | VIRTUAL GENERATED INVISIBLE | | PetHotel | Dogs | GoodDog | bit | INVISIBLE | +--------------+------------+-------------+-----------+-----------------------------+
The SHOW CREATE TABLE
Statement
We can alternatively use the SHOW CREATE TABLE
statement to return the CREATE TABLE
statement used to create the table:
SHOW CREATE TABLE t1;
Result:
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | t1 | CREATE TABLE `t1` ( `c1` varchar(20) DEFAULT NULL, `c2` varchar(20) DEFAULT NULL, `c3` varchar(20) DEFAULT 'Salad' /*!80023 INVISIBLE */ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
We can see the /*!80023 INVISIBLE */
part, which indicates that it’s an invisible column.
The mysqlshow
Client
Another way to find invisible columns is with the mysqlshow
client. This is a separate client, so you run this from the command line (i.e. not from within MySQL itself).
So, we can check the above table by opening the command line (e.g. open a new Terminal window) and entering the following:
mysqlshow -u root KrankyKranes t1
Result:
+-------+-------------+--------------------+------+-----+---------+-----------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-------+-------------+--------------------+------+-----+---------+-----------+---------------------------------+---------+ | c1 | varchar(20) | utf8mb4_0900_ai_ci | YES | | | | select,insert,update,references | | | c2 | varchar(20) | utf8mb4_0900_ai_ci | YES | | | | select,insert,update,references | | | c3 | varchar(20) | utf8mb4_0900_ai_ci | YES | | Salad | INVISIBLE | select,insert,update,references | | +-------+-------------+--------------------+------+-----+---------+-----------+---------------------------------+---------+
Here, I specified the KrankyKranes
database and the root
user. I specified the t1
table after the database.
We can see that various columns of information are returned, including the Extra
column, which tells us if the column is invisible.