Updated on 2024-11-11 GMT+08:00

DML

Table 1 DML syntax compatibility

No.

Description

Syntax

Difference

1

DELETE supports deleting data from multiple tables.

DELETE

  • During multi-table deletion, if a tuple to be deleted is concurrently modified by other sessions, the latest values of all tuples in the session are used for matching again. If the conditions are still met, the tuple is deleted. During this process, MySQL deletes all target tables in the same way. However, GaussDB only rematches tuples in the target tables that involve concurrent updates, which may cause data inconsistency.
  • The verification rules of target tables and range tables in the multi-table operation syntax are different from those in MySQL. After the GUC compatibility parameter m_format_dev_version is set to 's2', the verification rules become consistent with MySQL.

2

DELETE supports ORDER BY and LIMIT.

DELETE

-

3

DELETE supports deleting data from a specified partition (or subpartition).

DELETE

-

4

UPDATE supports updating data from multiple tables.

UPDATE

During multi-table update, if a tuple to be updated is concurrently modified by other sessions, the latest values of all tuples in the session are used for matching again. If the conditions are still met, the tuple is updated. During this process, MySQL updates all target tables consistently. However, GaussDB only rematches tuples of target tables that involve concurrent updates, which may cause data inconsistency.

5

UPDATE supports ORDER BY and LIMIT.

UPDATE

-

6

Support the SELECT INTO syntax.

SELECT

  • In GaussDB, you can use SELECT INTO to create a table based on the query result. MySQL does not support this function.
  • In GaussDB, the SELECT INTO syntax does not support the query result that is obtained after the set operation of multiple queries is performed.

7

Support the REPLACE INTO syntax.

REPLACE

Difference between the initial values of the time type. For example:
  • MySQL is not affected by the strict or loose mode. You can insert time 0 into a table.
    mysql> CREATE TABLE test(f1 TIMESTAMP NOT NULL, f2 DATETIME NOT NULL, f3 DATE NOT NULL);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> REPLACE INTO test VALUES(f1, f2, f3);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> SELECT * FROM test;
    +---------------------+---------------------+------------+
    | f1                  | f2                  | f3         |
    +---------------------+---------------------+------------+
    | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 | 0000-00-00 |
    +---------------------+---------------------+------------+
    1 row in set (0.00 sec)
  • The time 0 can be successfully inserted only when GaussDB is in loose mode.
    gaussdb=# SET sql_mode = '';
    SET
    gaussdb=# CREATE TABLE test(f1 TIMESTAMP NOT NULL, f2 DATETIME NOT NULL, f3 DATE NOT NULL);
    CREATE TABLE
    gaussdb=# REPLACE INTO test VALUES(f1, f2, f3);
    REPLACE 0 1
    gaussdb=# SELECT * FROM test;
    f1          |         f2          |     f3
    ---------------------+---------------------+------------
    0000-00-00 00:00:00 | 0000-00-00 00:00:00 | 0000-00-00
    (1 row)

    In strict mode, the error "Incorrect Date/Time/Datetime/Timestamp/Year value" is reported.

8

SELECT supports multi-partition query.

SELECT

-

9

UPDATE supports multi-partition update.

UPDATE

-

10

Import data by using LOAD DATA.

LOAD DATA

When LOAD DATA is used to import data, GaussDB differs from MySQL in the following aspects:

  • The execution result of the LOAD DATA syntax is the same as that in M* strict mode. The loose mode is not adapted currently.
  • The IGNORE and LOCAL parameters are used only to ignore the conflicting rows when the imported data conflicts with the data in the table and to automatically fill default values for other columns when the number of columns in the file is less than that in the table. Other functions are not supported currently.
  • If the keyword LOCAL is specified and the file path is a relative path, the file is searched from the binary directory. If the keyword LOCAL is not specified and the file path is a relative path, the file is searched from the data directory.
  • LOAD DATA can only be used to import files from the server.
  • The [(col_name_or_user_var [, col_name_or_user_var]...)] parameter cannot be used to specify a column repeatedly.
  • The newline character specified by [FIELDS TERMINATED BY 'string'] cannot be the same as the separator specified by [LINES TERMINATED BY'string'].
  • If the data written to a table by running LOAD DATA cannot be converted to the data type of the table, an error is reported.
  • The LOAD DATA SET expression does not support the calculation of a specified column name.
  • LOAD DATA applies only to tables but not views.
  • The default newline character of the file in Windows is different from that in Linux. LOAD DATA cannot identify this scenario and reports an error. You are advised to check the newline character at the end of lines in the file to be imported.

11

INSERT supports the VALUES reference column syntax.

INSERT INTO tabname VALUES(1,2,3) ON DUPLICATE KEY UPDATE b = VALUES(column_name)

The format of table-name.column-name is not supported by VALUES() in the ON DUPLICATE KEY UPDATE clause in GaussDB, but is supported in MySQL.

12

LIMIT differences

DELETE, SELECT, and UPDATE

The LIMIT clauses of each statement in GaussDB are different from those in MySQL.

The maximum parameter value of LIMIT (of the BIG INT type) in GaussDB is 9223372036854775807. If the actual value exceeds the number, an error is reported. In MySQL, the maximum value of LIMIT (of the unsigned LONGLONG type) is 18446744073709551615. If the actual value exceeds the number, an error is reported.

You can set a small value in LIMIT, which is rounded off during execution. The value cannot be a decimal in MySQL.

In a DELETE statement, GaussDB does not allow limit to be 0, while MySQL allows limit to be 0.

13

Difference in using backslashes (\)

INSERT

The usage of backslashes (\) can be determined by parameters in GaussDB and MySQL, but their default usages are different.

In MySQL, the NO_BACKSLASH_ESCAPES parameter is used to determine whether backslashes (\) in character strings and identifiers are parsed as common characters or escape characters. By default, backslashes (\) are parsed as escape characters in character strings and identifiers. If set sql_mode is set to 'NO_BACKSLASH_ESCAPES', backslashes (\) cannot be parsed as escape characters in character strings and identifiers.

In GaussDB, the standard_conforming_strings parameter is used to determine whether backslashes (\) in character strings and identifiers are parsed as common characters or escape characters. The default value is on, indicating that backslashes (\) are parsed as common text in common character string texts according to the SQL standard. If set standard_conforming_strings is set to off, backslashes (\) can be parsed as escape characters in character strings and identifiers.

14

If the inserted value is less than the number of columns, MySQL reports an error while GaussDB supplements null values.

INSERT

In GaussDB, if the column list is not specified and the inserted value is less than the number of columns, values are assigned based on the column sequence when the table is created by default. If a column has a NOT NULL constraint, an error is reported. If no NOT NULL constraint exists and a default value is specified, the default value is added to the column. If no default value is specified, null is added.

15

The columns sorted in ORDER BY must be included in the columns of the result set.

SELECT

In GaussDB, when used with the GROUP BY clause, the columns to be sorted in ORDER BY must be included in the columns of the result set retrieved by the SELECT statement. When used with the DISTINCT keyword, the columns to be sorted in ORDER BY must be included in the columns of the result set retrieved by the SELECT statement.

16

Do not use ON DUPLICATE KEY UPDATE to modify constraint columns.

INSERT

-

17

Duplicate column names are allowed in the SELECT result.

SELECT

-

18

NATURAL JOIN in GaussDB is different from that in MySQL.

SELECT

In GaussDB, NATURAL [ [LEFT | RIGHT] OUTER] JOIN allows you not to specify LEFT | RIGHT. If LEFT | RIGHT is not specified, NATURAL OUTER JOIN is NATURAL JOIN. You can use JOIN consecutively.

19

If the foreign key data type is timestamp or datetime, an error is reported for attempts to update or delete the foreign table.

UPDATE/DELETE

If the foreign key data type is timestamp or datetime, an error is reported for attempts to update or delete the foreign table, but in MySQL the table can be updated or deleted.

20

Compatibility in terms of nature join and using

SELECT

  • In GaussDB, join sequence is strictly from left to right. MySQL may adjust the sequence.
  • In GaussDB and MySQL, columns involving join in the left or right table cannot be ambiguous during natural join or using. (Generally, ambiguity is caused by duplicate names of columns in the left or right temporary table.) The join sequence differs in two databases, which may lead to different behaviors.
    • Behavior in GaussDB:
      m_regression=# CREATE TABLE t1(a int,b int);
      CREATE TABLE
      m_regression=# CREATE TABLE t2(a int,b int);
      CREATE TABLE
      m_regression=# CREATE TABLE t3(a int,b int);
      CREATE TABLE
      m_regression=# SELECT * FROM t1 JOIN t2;
       a | b | a | b 
      ---+---+---+---
      (0 rows)
      m_regression=# SELECT * FROM t1 JOIN t2 natural join t3; -- Failed. Duplicate contents exist in columns a and b of the temporary table obtained by t1 join t2. Therefore, there is ambiguity in nature join.
      ERROR:  common column name "a" appears more than once in left table
    • Behavior in MySQL:
      mysql> SELECT * FROM t1 JOIN t2 NATURAL JOIN t3;
      Empty set (0.00 sec)
      mysql> SELECT * FROM (t1 join t2) NATURAL JOIN t3;
      ERROR 1052 (23000): Column 'a' in from clause is ambiguous

21

The WITH clause is compatible with MySQL 8.0.

SELECT, INSERT, UPDATE, and DELETE

-

22

Compatibility in terms of join

SELECT

Commas (,) cannot be used as a way of join in GaussDB, but can be used in MySQL.

GaussDB does not support use index for join.

23

Displaying column names in the SELECT statement

SELECT

  • To ensure that the column names displayed in the SELECT statement are the same as those in MySQL, you need to enable the parameter to display the column name output.
    SET m_format_behavior_compat_options = 'select_column_name'
  • If this configuration item is not set:
    • SELECT System function: The output is the system function name.
    • SELECT Expression: The output is ?column?.
    • SELECT Boolean value: The output is a Boolean value.
  • If this configuration item is set, the column name is displayed as all functions or expressions.
    • The MySQL client ignores common comments, but the gsql and PyMySQL clients do not.
    • The MySQL server converts comments starting with /*! into executable statements. An M-compatible database does not support such comments and processes them as common comments.
    • If an expression contains two hyphens (--) that is not followed by a space, an M-compatible database cannot identify the two hyphens as a comment, whereas the MySQL server identifies it as two hyphens (--).
    • If the displayed column name string contains escape characters, the escaped characters are displayed only when m_format_behavior_compat_options is set to enable_escape_string. Otherwise, the escape characters are displayed. For example, in an M-compatible database, "SELECT"abc\tdef";" is displayed as abc\tdef when the preceding option is disabled.
      m_db=# SET m_format_behavior_compat_options='select_column_name,enable_escape_string';
      SET
      m_db=# SELECT "abc\tdef";
       abc     def 
      -------------
       abc     def
      (1 row)
      
      m_db=# SET m_format_behavior_compat_options='select_column_name';
      SET
      m_db=# SELECT "abc\tdef";
       abc\tdef 
      ----------
       abc\tdef
      (1 row)
    • If a column name contains more than 63 characters, the extra characters will be truncated.
    • If the last part of an expression is a comment, the last comment and the space connected to the comment are not displayed.
      m_db=# SELECT 123        /* 456 */;
       123 
      -----
       123
      (1 row)
    • If an expression is a Boolean value, the command output is TRUE or FALSE regardless of the input case.
      m_db=# SELECT true;
       TRUE 
      ------
       t
      (1 row)
    • If an expression is null, the command output is NULL regardless of the input case.
      m_db=# SELECT null;
       NULL 
      ------
      
      (1 row)
    • If an expression contains a hyphen (-), all inputs are output as column names.
      m_db=# SELECT (+-+1);
       (+-+1) 
      --------
           -1
      (1 row)
      
      m_db=# SELECT -true;
       -true 
      -------
          -1
      (1 row)
      
      m_db=# SELECT -null;
       -null 
      -------
      
      (1 row)
  • When pymysql is used to execute the SELECT statement, the prefix of the queried character string does not use ASCII characters, and the database is not encoded in UTF-8, the displayed column names are different from those in MySQL.

24

SELECT export file (into outfile)

SELECT ... INTO OUFILE ...

In the file exported by using the SELECT INTO OUTFILE syntax, the display precision of values of the FLOAT, DOUBLE, and REAL types in GaussDB is different from that in MySQL. The syntax does not affect the import using COPY the values after import.

25

UPDATE/INSERT/REPLACE ... SET specifies the schema name and table name.

UPDATE/INSERT/REPLACE ... SET

The three-segment format for UPDATE/REPLACE SET is database.table.column in MySQL, and is table.column.filed in GaussDB, where filed indicates the attribute in the specified composite type.

For INSERT ... SET, MySQL supports column, table.column, and database.table.column. GaussDB supports only column and does not support table.column and database.table.column.

26

The execution sequence of UPDATE SET is different from that of MySQL.

UPDATE ... SET

In MySQL, UPDATE SET is performed in sequence. The results of UPDATE at the front affect subsequent results of UPDATE, and the same column can be set for multiple times. In GaussDB, all related data is obtained first, and then UPDATE is performed on the data at a time. The same column cannot be set for multiple times. After the GUC compatibility parameter m_format_dev_version is set to 's2', the behavior can be the same as that in MySQL only in the single-table scenario. That is, the same column can be set for multiple times and the updated result is referenced.

27

IGNORE feature

UPDATE/DELETE/INSERT

The execution process in MySQL is different from that in GaussDB. Therefore, the number and information of generated warnings may be different.

28

SHOW COLUMNS syntax

SHOW

  • User permission verification is different from that of MySQL.
    • In GaussDB, you need the USAGE permission on the schema of a specified table and table-level or column-level permissions on the specified table. Only information about columns with the SELECT, INSERT, UPDATE, REFERENCES, and COMMENT permissions is displayed.
    • In MySQL, you need table-level or column-level permissions on a specified table. Only information about columns with the SELECT, INSERT, UPDATE, REFERENCES, and COMMENT permissions is displayed.
  • When the LIKE and WHERE clauses involve string comparison, the fields Field, Collation, Null, Extra, and Privileges use the character set utf8mb4 and the collation utf8mb4_general_ci, and the fields Type, Key, Default, and Comment use the character set utf8mb4 and the collation utf8mb4_bin.
  • In GaussDB, you are advised not to select columns other than the returned fields in the WHERE clause. Otherwise, unexpected errors may occur.
    -- Expected error
    m_db=# SHOW FULL COLUMNS FROM t02 WHERE `b`='pri';
    ERROR:  Column "b" does not exist.
    LINE 1: SHOW FULL COLUMNS FROM t02 WHERE `b`='pri';
                                             ^
    
    -- Unexpected error
    m_db=# SHOW FULL COLUMNS FROM t02 WHERE `c`='pri';
    ERROR:  input of anonymous composite types is not implemented
    LINE 1: SHOW FULL COLUMNS FROM t02 WHERE `c`='pri';
                                                 ^

29

SHOW CREATE DATABASE syntax

SHOW

User permission verification is different from that of MySQL.

  • In GaussDB, you need the USAGE permission on a specified schema.
  • In MySQL, you need database-level permissions (except GRANT OPTION and USAGE), table-level permissions (except GRANT OPTION), or column-level permissions.

30

SHOW CREATE TABLE syntax

SHOW

  • User permission verification is different from that of MySQL.
    • In GaussDB, you need the USAGE permission on the schema where a specified table is located and table-level permissions on the specified table.
    • Table-level permissions (except GRANT OPTION) of the specified table are required in MySQL.
  • The returned statements for table creation are different from those in MySQL.
    • In GaussDB, indexes are returned as CREATE INDEX statements. In MySQL, indexes are returned as CREATE TABLE statements. In GaussDB, the range of optional parameters supported by the CREATE INDEX syntax is different from that supported by the CREATE TABLE syntax. Therefore, some indexes cannot be created in CREATE TABLE statements.
    • In GaussDB, the ENGINE and ROW_FORMAT options of CREATE TABLE are adapted only for the syntax but do not take effect. Therefore, they are not displayed in the returned statements for table creation.
  • These statements are compatible with MySQL only after the compatibility parameter m_format_dev_version is set to 's2'. The compatibility parameter takes effect by changing the positions of column comments, table comments, ON COMMIT option for global temporary tables, primary key and unique constraints (where the USING INDEX TABLESPACE option is no longer displayed), and index comments.

31

SHOW CREATE VIEW syntax

SHOW

  • User permission verification is different from that of MySQL.
    • In GaussDB, you need the USAGE permission on the schema where a specified view is located and table-level permissions on the specified view.
    • In MySQL, you need the table-level SELECT and table-level SHOW VIEW permissions on the specified view.
  • The returned statements for view creation are different from those in MySQL. If a view is created in the format of SELECT * FROM tbl_name, * is not expanded in GaussDB but expanded in MySQL.
  • The character_set_client and collation_connection fields in the returned result are different from those in MySQL.
    • The session values of system variables character_set_client and collation_connection are displayed during view creation in MySQL
    • Related metadata is not recorded in GaussDB and NULL is displayed.

32

SHOW PROCESSLIST syntax

SHOW

In GaussDB, the field content and case in the query result of this command are the same as those in the information_schema.processlist view. In MySQL, the field content and case may be different.

  • In GaussDB, common users can access only their own thread information. Users with the SYSADMIN permission can access thread information of all users.
  • In MySQL, common users can access only their own thread information. Users with the PROCESS permission can access thread information of all users.

33

SHOW [STORAGE] ENGINES

SHOW

In GaussDB, the field content and case of the query result of this command are the same as those in the information_schema.engines view. In MySQL, they may be different from those in the view. The query results of this command are different in MySQL and GaussDB because the databases have different storage engines.

34

SHOW [SESSION] STATUS

SHOW

In GaussDB, the field content and case of the query result of this command are the same as those in the information_schema.session_status view. In MySQL, they may be different from those in the view. Currently, GaussDB supports only Threads_connected and Uptime.

35

SHOW [GLOBAL] STATUS

SHOW

In GaussDB, the field content and case of the query result of this command are the same as those in the information_schema.global_status view. In MySQL, they may be different from those in the view. Currently, GaussDB supports only Threads_connected and Uptime.

36

SHOW INDEX

SHOW

  • User permission verification is different from that of MySQL.
    • In GaussDB, you need the USAGE permission on a specified schema and table-level or column-level permissions on a specified table.
    • In MySQL, you need table-level (except GRANT OPTION) or column-level permission on the specified table.
  • Temporary tables in GaussDB are stored in independent temporary schemas. When using the FROM or IN db_name condition to display the index information of a specified temporary table, you must specify db_name as the schema where the temporary table is located. Otherwise, the system displays a message indicating that the temporary table does not exist. This is different from MySQL in some cases.
  • In the query result of GaussDB, the Table, Index_type, and Index_comment columns use the character set utf8mb4 and collation utf8mb4_bin. The Key_name, Column_name, Collation, Null, and Comment columns use the character set utf8mb4 and collation utf8mb4_general_ci.

37

SHOW SESSION VARIABLES

SHOW

In GaussDB, the field content and case of the query result are the same as those in the information_schema.session_variables view. In MySQL, they may be different from those in the view.

In GaussDB, when LIKE and WHERE are used to select fields in the query result, the sorting rule is the same as that of the corresponding fields in the information_schema.session_variables view.

38

SHOW GLOBAL VARIABLES

SHOW

In GaussDB, the field content and case of the query result of this command are the same as those in the information_schema.global_variables view. In MySQL, they may be different from those in the view.

In GaussDB, when LIKE and WHERE are used to select fields in the query result, the sorting rule is the same as that of the corresponding fields in the information_schema.global_variables view.

39

SHOW CHARACTER SET

SHOW

In GaussDB, the field content and case of the query result are the same as those in the information_schema.character_sets view. In MySQL, they may be different from those in the view.

In GaussDB, when LIKE and WHERE are used to select fields in the query result, the sorting rule is the same as that of the corresponding fields in the information_schema.character_sets view.

40

SHOW COLLATION

SHOW

In GaussDB, the field content and case of the query result are the same as those in the information_schema.collations view. In MySQL, they may be different from those in the view.

In GaussDB, when LIKE and WHERE are used to select fields in the query result in GaussDB, the sorting rule is the same as that of the corresponding fields in the information_schema.collations view.

41

EXCEPT Syntax

SELECT

-

42

SELECT supports the STRAIGHT_JOIN syntax.

SELECT

The execution plans generated in the multi-table JOIN scenarios in GaussDB may be different from those in MySQL.

43

SHOW TABLES

SHOW

  • The LIKE behavior is different. For details, see "LIKE" in Operators.
  • The WHERE expression behavior is different. For details, see "WHERE" in GaussDB.
  • In GaussDB, permissions on tables and databases must be assigned to users separately. The database to be queried must be available to users on the SHOW SCHEMAS. Users must have permissions on both tables and databases. MySQL can be accessed as long as you have table permissions.
  • In GaussDB, the verification logic preferentially checks whether a schema exists and then checks whether the current user has the permission on the schema, which is different from that in MySQL.
  • In GaussDB, fields in the query result use the character set utf8mb4 and collation utf8mb4_bin.
  • In the LIKE clause of GaussDB, if the target database is information_schema, the pattern is converted to lowercase letters before matching. In MySQL 8.0, when the target database is information_schema, the pattern is converted to uppercase letters before matching.

44

SHOW TABLE STATUS

SHOW

  • In GaussDB, the syntax displays data depending on the tables view under information_schema. In MySQL, the tables view specifies tables.
  • In GaussDB, permissions on tables and databases must be assigned to users separately. The database to be queried must be available to users on the SHOW SCHEMAS. Users must have permissions on both tables and databases. MySQL can be accessed as long as you have table permissions.
  • In GaussDB, the verification logic preferentially checks whether a schema exists and then checks whether the current user has the permission on the schema, which is different from that in MySQL.
  • In GaussDB, when LIKE and WHERE are used to select fields in the query result, the sorting rule is the same as that of the corresponding fields in the information_schema.tables view.
  • In the LIKE clause of GaussDB, if the target database is information_schema, the pattern is converted to lowercase letters before matching. In MySQL 8.0, when the target database is information_schema, the pattern is converted to uppercase letters before matching.

45

WITH ROLLUP is supported after GROUP BY.

SELECT

WITH ROLLUP and ORDER BY can be used together in GaussDB, but cannot in MySQL.

46

The ONLY_FULL_GROUP_BY option in SQL mode is supported.

SELECT

If the non-aggregate function column in the SELECT list is inconsistent with the GROUP BY field, when all non-aggregate function columns are in the GROUP BY list or WHERE list and the column in the WHERE clause is equal to a constant, no error is reported. For the column in the WHERE clause, GaussDB supports function column expressions whose input parameter is 1, but MySQL does not support function column expressions.

In GaussDB, the field following GROUP BY must be a positive integer.

47

HAVING syntax

SELECT

In GaussDB, HAVING can only reference columns in the GROUP BY clause or columns used in aggregate functions. However, MySQL supports more: it allows HAVING to reference SELECT columns in the list and columns in external subqueries.

48

Using SELECT to query system parameters and user variables

SELECT @variable, SELECT @@variable

  • In MySQL, user variables can be queried without adding specific variable names (that is, SELECT @). GaussDB does not support this feature.

    Behavior in MySQL:

    mysql> SELECT @;
    +------------+
    | @          |
    +------------+
    | NULL       |
    +------------+
    1 row in set (0.00 sec)
    Behavior in GaussDB:
    m_db=# SELECT @;
    ERROR:  syntax error at or near "@"
    LINE 1: SELECT @;
                   ^
  • When the type of the queried system variable is BOOLEAN, the output result is t or f in GaussDB and 1 or 0 in MySQL. The BOOLEAN type is actually mapped to the TINYINT type.

49

Subqueries

SELECT

  • In GaussDB, the subquery result cannot contain multiple columns. If the subquery result contains multiple columns, an error is reported. In MySQL, the subquery result can contain multiple columns.

    Behavior in MySQL:

    mysql> SELECT row(1,2) = (SELECT 1,2);
    +-------------------------+
    | row(1,2) = (select 1,2) |
    +-------------------------+
    |                       1 |
    +-------------------------+
    1 row in set (0.00 sec)

    Behavior in GaussDB:

    m_db=# SELECT row(1,2) = (SELECT 1,2);
    ERROR:  subquery must return only one column
    LINE 1: SELECT row(1,2) = (SELECT 1,2);                          ^
  • In the scenario where precision transfer is enabled, if the return type in the FROM clause of a subquery is numeric in MySQL, one of the following conditions is met:
    • The SELECT clause contains GROUP BY.
    • The SELECT clause contains HAVING.
    • The SELECT clause contains DISTINCT.
    • The SELECT clause contains LIMIT.
    • The SELECT clause does not contain FROM table.
    • The SELECT clause contains a statement that assigns a value to a user-defined variable.

    Precision truncation may occur. If this type of subquery is used as the intermediate calculation value for the next operation, the precision of GaussDB is higher than that of MySQL.

    Behavior in MySQL:

    mysql> select greatest((select * from (select distinct c2/1.61 from t_time) t4), 1.00000000000000000);
    +-----------------------------------------------------------------------------------------+
    | greatest((select * from (select distinct c2/1.61 from t_time) t4), 1.00000000000000000) |
    +-----------------------------------------------------------------------------------------+
    |                                                                 39144.72670800000000000 |
    +-----------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)

    Behavior in GaussDB:

    m_db=# select greatest((select * from (select distinct c2/1.61 from t_time) t4), 1.00000000000000000); 
            greatest         
    -------------------------
     39144.72670807453416149
    (1 row)

    In addition, PBE is used together with user-defined variables. If the preceding conditions are met, MySQL outputs results with the precision of 30 decimal places. Otherwise, the MySQL outputs results with the original precision, but GaussDB always outputs results with the precision of 30 decimal places. For example:

    Behavior in MySQL:

    -- The preceding conditions are met:
    mysql> SET @var6=12.1234567891;
    Query OK, 0 rows affected (0.00 sec)
    mysql> PREPARE p1 FROM "SELECT * FROM (SELECT @var6) t";
    Query OK, 0 rows affected (0.00 sec)
    Statement prepared
    mysql> EXECUTE p1;
    +-----------------------------------+
    | @var6                             |
    +-----------------------------------+
    | 12.123456789100000000000000000000 |
    +-----------------------------------+
    1 row in set (0.00 sec)
    -- The preceding conditions are not met:
    mysql> PREPARE p1 FROM "SELECT * FROM (SELECT @var6 FROM (SELECT 1) v1) t";
    Query OK, 0 rows affected (0.00 sec)
    Statement prepared
    mysql> EXECUTE p1;
    +---------------+
    | @var6         |
    +---------------+
    | 12.1234567891 |
    +---------------+
    1 row in set (0.00 sec)

    Behavior in GaussDB:

    -- The preceding conditions are met:
    m_db=# SET @var6=12.1234567891;
    SET
    m_db=# PREPARE p1 FROM "SELECT * FROM (SELECT @var6) t";
    PREPARE
    m_db=# EXECUTE p1;
                   @var6               
    -----------------------------------
     12.123456789100000000000000000000
    (1 row)
    -- The preceding conditions are not met:
    m_db=# PREPARE p1 FROM "SELECT * FROM (SELECT @var6 FROM (SELECT 1) v1) t";
    PREPARE
    m_db=# EXECUTE p1;
                   @var6               
    -----------------------------------
     12.123456789100000000000000000000
    (1 row)

50

SHOW DATABASES

SHOW

In GaussDB, fields in the query result use the character set utf8mb4 and collation utf8mb4_bin.

51

SELECT followed by a row expression

SELECT

In MySQL, SELECT cannot be followed by a row expression, but in GaussDB, SELECT can be followed by a row expression.

Behavior in MySQL:

mysql> SELECT row(1,2);
ERROR 1241 (21000): Operand should contain 1 column(s)

Behavior in GaussDB:

m_db=# SELECT row(1,2);
 row(1,2) 
----------
 (1,2)
(1 row)

52

SELECT view query, subquery, or UNION involves the carry difference when NUMERIC is converted to TIME or DATETIME.

SELECT

In some SELECT scenarios, the results of the TIME/DATETIME type are different from those of MySQL.

Difference scenarios involving conversion from NUMERIC to TIME/DATETIME: view query, subquery, and UNION.

Differential behavior: The SELECT behavior of GaussDB is unified. When the NUMERIC type is converted to the TIME or DATETIME type, only the maximum precision bit(6) is carried. In MySQL view query, subquery, and UNION scenarios, carry is performed based on the actual precision of a result.

Behavior in MySQL:

-- In a simple query, carry is performed only on the result with the precision of 6, which is the maximum. Therefore, 11:11:00.00002 is output.
mysql> SELECT maketime(11, 11, 2.2/time '08:30:23.01');
+------------------------------------------+
| maketime(11, 11, 2.2/time '08:30:23.01') |
+------------------------------------------+
| 11:11:00.00002                           |
+------------------------------------------+
1 row in set (0.01 sec)

-- In a subquery, carry is performed based on the actual result precision. Therefore, 11:11:00.00003 is output.
mysql> SELECT * FROM (SELECT maketime(11, 11, 2.2/time '08:30:23.01')) f1;
+------------------------------------------+
| maketime(11, 11, 2.2/time '08:30:23.01') |
+------------------------------------------+
| 11:11:00.00003                           |
+------------------------------------------+
1 row in set (0.00 sec)

Behavior in GaussDB:

m_db=# SET m_format_behavior_compat_options= 'enable_precision_decimal';
SET

-- In a simple query, carry is performed only on the result with the precision of 6, which is the maximum. Therefore, 11:11:00.00002 is output.
m_db=# SELECT maketime(11, 11, 2.2/time '08:30:23.01');
    maketime
----------------
 11:11:00.00002
(1 row)

-- In a simple query, carry is performed only on the result with the precision of 6, which is the maximum, and the result precision is 5. Therefore, 11:11:00.00002 is output.
m_db=# SELECT * FROM (SELECT maketime(11, 11, 2.2/time '08:30:23.01')) f1;
    maketime
----------------
 11:11:00.00002
(1 row)

53

Differences of SELECT in calculating and processing date and time functions of the numeric type and subquery

SELECT

When date and time functions of the numeric type and subquery are calculated using SELECT, if the GUC parameter m_format_behavior_compat_options is set to enable_precision_decimal, GaussDB converts the value of the date and time type returned by the function to the one of the numeric type and then performs calculation based on the numeric type. The result is also of the numeric type. MySQL truncates the values returned by the date and time functions in scenarios such as subquery condition query and group query.

Behavior in MySQL:

mysql> select 1.5688 * (select ADDDATE('2020-10-20', interval 1 day) where true group by 1 having true);
+--------------------------------------------------------------------------------+
| 1.5688 * (select ADDDATE('2020-10-20', interval 1 day) where true having true) |
+--------------------------------------------------------------------------------+
|                                                                       3168.976 |

Behavior in GaussDB:

m_db=# select 1.5688 * (select ADDDATE('2020-10-20', interval 1 day) where true group by 1 having true);
      ?column?      
--------------------
 31691361.744799998
(1 row)

54

Differences in unsigned types when SELECT nests subqueries

SELECT

When SELECT nests subqueries, the unsigned type is not overwritten, which is different from MySQL 5.7.

Behavior in MySQL 5.7:

mysql> drop table if exists t1;
Query OK, 0 rows affected (0.02 sec)

mysql> create table t1 (
    ->     c10 real(10, 4) zerofill
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into t1 values(123.45);
Query OK, 1 row affected (0.00 sec)

mysql> desc t1;
+-------+--------------------------------+------+-----+---------+-------+
| Field | Type                           | Null | Key | Default | Extra |
+-------+--------------------------------+------+-----+---------+-------+
| c10   | double(10,4) unsigned zerofill | YES  |     | NULL    |       |
+-------+--------------------------------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> create table t1_sub_1 as select (select * from t1);
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> desc t1_sub_1;
+--------------------+--------------+------+-----+---------+-------+
| Field              | Type         | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+-------+
| (select * from t1) | double(10,4) | YES  |     | NULL    |       |
+--------------------+--------------+------+-----+---------+-------+
1 row in set (0.00 sec)

Behavior in GaussDB:

test=# DROP TABLE IF EXISTS t1;
DROP TABLE
test=# CREATE TABLE t1 (
test(#     c10 real(10, 4) ZEROFILL
test(# );
CREATE TABLE
test=# INSERT INTO t1 VALUES(123.45);
INSERT 0 1
test=# DESC t1;
 Field |              Type              | Null | Key | Default | Extra 
-------+--------------------------------+------+-----+---------+-------
 c10   | double(10,4) unsigned zerofill | YES  |     |         | 
(1 row)
test=# CREATE TABLE t1_sub_1 AS SELECT (SELECT * FROM t1);
INSERT 0 1
test=# DESC t1_sub_1;
 Field |         Type          | Null | Key | Default | Extra 
-------+-----------------------+------+-----+---------+-------
 c10   | double(10,4) unsigned | YES  |     |         | 
(1 row)

55

SELECT FOR SHRAE/FOR UPDATE/LOCK IN SHRAE MODE

SELECT

  • The FOR SHARE/FOR UPDATE/LOCK IN SHARE MODE and UNION/EXCEPT/DISTINCT/GROUP BY/HAVING clauses cannot be used together in GaussDB. They can be used together in MySQL 5.7 (except in the FOR SHARE/EXCEPT syntax) and MySQL 8.0.
  • When a lock clause is used together with the LEFT/RIGHT [OUTER] JOIN clause, the LEFT JOIN cannot be used to lock the right table, and the RIGHT JOIN clause cannot be used to lock the left table. In MySQL, tables on both sides of JOIN can be locked at the same time.

56

SELECT syntax

SELECT

  • In GaussDB, when the table alias in the FROM clause is specified, the table alias can contain the column name. In MySQL 5.7, the table alias cannot contain the column name. In MySQL 8.0, the table alias can contain the column name only when the subquery is specified.
-- GaussDB
m_db=# DROP TABLE IF EXISTS t1;
DROP TABLE
m_db=# CREATE TABLE t1(a INT, b INT);
CREATE TABLE
m_db=# INSERT INTO t1 VALUES(1,2);
INSERT 0 1
m_db=# SELECT * FROM t1 t2(a, b);
 a | b 
---+---
 1 | 2
(1 row)

m_db=# SELECT * FROM (SELECT * FROM t1) t2(a, b);
 a | b 
---+---
 1 | 2
(1 row)

-- MySQL5.7
mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE TABLE t1(a INT, b INT);
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t1 VALUES(1,2);
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM t1 t2(a, b);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(a, b)' at line 1
mysql> SELECT * FROM (SELECT * FROM t1) t2(a, b);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(a, b)' at line 1

-- MySQL8.0
mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected (0.10 sec)

mysql> CREATE TABLE t1(a INT, b INT);
Query OK, 0 rows affected (0.18 sec)

mysql> INSERT INTO t1 VALUES(1,2);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM t1 t2(a, b);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(a, b)' at line 1
mysql> SELECT * FROM (SELECT * FROM t1) t2(a, b);
+------+------+
| a    | b    |
+------+------+
|    1 |    2 |
+------+------+
1 row in set (0.00 sec)
  • If a query statement does not contain the FROM clause, GaussDB supports the WHERE clause, which is the same as that in MySQL 8.0. MySQL 5.7 does not support the WHERE clause.
-- GaussDB
m_db=# SELECT 1 WHERE true;
 1 
---
 1
(1 row)

-- MySQL5.7
mysql> SELECT 1 WHERE true;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where true' at line 1

-- MySQL8.0
mysql> SELECT 1 WHERE true;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

57

When statements such as UNION and GROUP BY that do not carry the ORDER BY clause are used to merge or aggregate data, the output data sequence may not be the same as that in MySQL because the executor operators are different.

SELECT

Take the GROUP BY scenario as an example. If the hashagg operator is used, the sequence is different from the original one. You are advised to add the ORDER BY clause in the scenario where the data sequence needs to be ensured.

-- Initialize data.
DROP TABLE IF EXISTS test;
CREATE TABLE test(id INT);
INSERT INTO test VALUES (1),(2),(3),(4),(5);
-- GaussDB
-- If precision transfer is disabled, the ID sequence is (1 3 2 4 5).
m_db=# SET m_format_behavior_compat_options= '';
SET
m_db=# SELECT /*+ use_hash_agg*/ id, pi() FROM test GROUP BY 1,2;
 id |        pi
----+-------------------
  1 | 3.141592653589793
  3 | 3.141592653589793
  2 | 3.141592653589793
  4 | 3.141592653589793
  5 | 3.141592653589793
(5 rows)
-- When the precision transfer function is enabled, the ID sequence changes to (5 4 2 3 1) due to the value change.
m_db=# SET m_format_behavior_compat_options= 'enable_precision_decimal';
SET
m_db=# SELECT /*+ use_hash_agg*/ id, pi() FROM test GROUP BY 1,2;
 id |    pi
----+----------
  5 | 3.141593
  4 | 3.141593
  2 | 3.141593
  3 | 3.141593
  1 | 3.141593
(5 rows)
-- In MySQL, the ID sequence is the original one.
mysql> SELECT id, pi() FROM test GROUP BY 1,2;
+------+----------+
| id   | pi()     |
+------+----------+
|    1 | 3.141593 |
|    2 | 3.141593 |
|    3 | 3.141593 |
|    4 | 3.141593 |
|    5 | 3.141593 |
+------+----------+
5 rows in set (0.00 sec)