E.6. Release 13.8-23.1

E.6.1. New feature
E.6.2. Optimize
E.6.3. Compatibility

Release date: 2023-03-30

E.6.1. New feature

  • Out of memory problems occur when memory is allocated, add detail and hint hints.

  • LightDB supports kubernetes(K8S) HA deployment,. The core modules include LightDB-patroni image and LightDB-operator image. LightDB-patroni image contains LightDB and Patroni for support HA deployment in container. LightDB-operator image are used to manage LightDB cluster in kubernetes.

  • Added guc parameter lightdb_server_version_num to identify the LightDB version number. This value cannot be modified at the session level, in the lightdb.conf configuration file. see SHOW.

    Show lightdb server version number:

    SHOW lightdb_server_version_num;
     lightdb_server_version_num 
    ----------------------------
     220400
    (1 row)
    

  • Added extension lt_sql_inspect to define transaction hours, as well as intercept and audit execution of dangerous SQL and commands during trading hours. see lt_sql_inspect.

E.6.2. Optimize

lt_probackup supports distributed optimization. see lt_distributed_probackup.

  • Added distributed backup ids in the script.

  • You can view the overall status of backups by distributed backup id.

E.6.3. Compatibility

E.6.3.1. MySQL compatible

  • Supports functions substr and substring. see function.

    for example:

    lightdb@postgres=# create database test_createdb_mysql with lightdb_syntax_compatible_type mysql;
    CREATE DATABASE
    lightdb@postgres=# \c test_createdb_mysql
    You are now connected to database "test_createdb_mysql" as user "lightdb".
    lightdb@test_createdb_mysql=# select substr('sadadertyui',-3,3) FROM DUAL;
     substr 
    --------
     yui
    (1 row)
    

  • Support MySQL division, including integer division by integer, division by 0 operation, etc see MySQL Compatible Functions.

    for example:

    lightdb@test_createdb_mysql=# select 4/0;
    WARNING:  division by zero
     ?column? 
    ----------
             
    (1 row)
    lightdb@test_createdb_mysql=# select 4/1;
          ?column?      
    --------------------
     4.0000000000000000
    (1 row)
    

  • Support for str_to_date function. see MySQL Compatible Functions.

    • Perpare statements are not supported for variable binding.

    • Due to the use of Julian days to express time, it is impossible to express the illegal date of 1999-00-00.

    • The lightdb_sql_mode value is no_zero_date, and the return value is an empty string, not NULL.

    • Illegal date error is reported, using LightDB error reporting logic.

    for example:

    select str_to_date('2022/09/10 11,13,13', '%Y/%m/%d %h,%i,%s');
          str_to_date     
    ---------------------
      2022-09-10 11:13:13
    (1 row)
    

  • Support for @ variables. see User Variable.

    • If the variable is not initialized, the type of the variable is text.

    • If the variable type is float, float8, the storage type is float8.

    • If the value of the variable is an integer type (smallint, bigint, int), the storage type is bigint

    • If the type of the variable is numeric, the storage type is numeric.

    • If the variable type is another type, the variable type is text.

    User variables are written as @var_name, where the variable name var_name must be an Identifiers or an Key Words. If you quote it identifier,var_name will be treated as a column name (for example, @"my-var"). @var_name and @ var_name are different. @var_name is a user variable expression, @ var_name is the absolute value of the column var_name.

    lightdb@test=# select @c1 := 5;
     @c1 
    -----
       5
    (1 row)
    
    lightdb@test=# SELECT c1, @c1, @ c1 FROM t;
     c1 | @c1 | ?column? 
    ----+-----+----------
      0 |   5 |        0
      1 |   5 |        1
    (2 rows)
    

  • Support specifying indexes when querying, only syntax support. force index enforces the use of the specified index; ignore index discards the specified index. see SELECT.

        -- multiple index
        select * from lt_test_mysql_ddl use index(pk_lt_test_mysql_ddl,uk_lt_test_mysql_ddl);
        select * from lt_test_mysql_ddl force index(pk_lt_test_mysql_ddl,uk_lt_test_mysql_ddl);
        select * from lt_test_mysql_ddl ignore index(pk_lt_test_mysql_ddl,uk_lt_test_mysql_ddl);
    
        -- multiple table join
        select * from lt_test_mysql_ddl a use index for order by(primary) join b using(id);
        select * from lt_test_mysql_ddl a force index for order by(pk_lt_test_mysql_ddl) join b using(id);
        select * from lt_test_mysql_ddl a ignore index for order by(primary,pk_lt_test_mysql_ddl) join b using(id);
        select * from lt_test_mysql_ddl a ignore index for order by(pk_lt_test_mysql_ddl) join b using(id);
       
  • Support specifying engine, collate, character set, comment and other attributes when creating a table, among which engine and comment are only supported syntaxally. Compatible with backquotes ('') and tinyint type compatible. see Integer Types.

  • Support duplicate key update syntax, when the PRIMARY KEY or UNIQU constraint is violated, update the operation, and vice versa. see ON DUPLICATE KEY UPDATE.

    INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=t1.c+1;
    
    UPDATE t1 SET c=c+1 WHERE a=1;
          
  • Support replace into syntax, when the PRIMARY KEY or UNIQU constraint is violated, delete the old tuple first, and then insert the new tuple. see REPLACE INTO.

    lightdb@testdb=# REPLACE INTO test VALUES (1, 'Old name', '18');
    INSERT 0 1
    
    lightdb@testdb=# REPLACE INTO test VALUES (1, 'New name');
    INSERT 0 1
    
    lightdb@testdb=# SELECT * FROM test;
     id |       name       | age 
    ----+------------------+-----
      1 | New name         |   0
    (1 row)
    

E.6.3.2. Oracle compatible

  • Added no_unnest and pq_distribute optimization prompts. see lt_hint_plan.

    no_unnest optimization prompts.

    lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 where exists(select * from test2 where test1.key1=test2.key1);
                   QUERY PLAN               
    ----------------------------------------
     Hash Join
       Hash Cond: (test1.key1 = test2.key1)
       ->  Seq Scan on test1
       ->  Hash
             ->  HashAggregate
                   Group Key: test2.key1
                   ->  Seq Scan on test2
    (7 rows)
    lightdb@postgres=# EXPLAIN (COSTS false) select * from test1 where exists(select/*+no_unnest*/ * from test2 where test1.key1=test2.key1);
                           QUERY PLAN                        
    ---------------------------------------------------------
     Seq Scan on test1 @"lt#1"
       Filter: (alternatives: SubPlan 1 or hashed SubPlan 2)
       SubPlan 1
         ->  Seq Scan on test2 @"lt#0"
               Filter: (test1.key1 = key1)
       SubPlan 2
         ->  Seq Scan on test2 test2_1 @"lt#0"
    (7 rows)
    

    pq_distribute optimization prompts.

    lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
    lightdb@lt_test-# EXPLAIN (COSTS false) SELECT /*+ leading(t1 t2) hashjoin(t1 t2)*/ * FROM t1 join t2 on t1.id=t2.id;
                        QUERY PLAN                     
    ---------------------------------------------------
     Gather
       Workers Planned: 3
       ->  Parallel Hash Join
             Hash Cond: (t1.id = t2.id)
             ->  Parallel Seq Scan on t1 @"lt#0"
             ->  Parallel Hash
                   ->  Parallel Seq Scan on t2 @"lt#0"
    (7 rows)
    lightdb@lt_test=# /*+set(parallel_tuple_cost 0) set(parallel_setup_cost 0) set(min_parallel_table_scan_size 0) set(min_parallel_index_scan_size 0) set(max_parallel_workers_per_gather 8)*/
    lightdb@lt_test-# EXPLAIN (COSTS false) select/*+leading(t1 t2) hashjoin(t1 t2) pq_distribute(t2 none broadcast)*/ * from t1 join t2 on t1.id=t2.id;
                     QUERY PLAN                  
    ---------------------------------------------
     Gather
       Workers Planned: 3
       ->  Hash Join
             Hash Cond: (t1.id = t2.id)
             ->  Parallel Seq Scan on t1 @"lt#0"
             ->  Hash
                   ->  Seq Scan on t2 @"lt#0"
    (7 rows)
    

  • Support Oracle to create user (CREATE USER)syntax; Supports cascading drop of users (DROP USER) and grant statements (see Examples).

    for example:

       CREATE USER user_name IDENTIFIED BY passwd DEFAULT TABLESPACE dt_space TEMPORARY TABLESPACE tt_space;
       DROP USER user_name CASCADE;
       GRANT CONNECT TO HS_SES;
       GRANT RESOURCE TO HS_SES;
       GRANT UNLIMITED TABLESPACE TO HS_SES;
    

  • Support global temporary tables. see Compatibility.

    • Support Oracle global temporary session tables.

    • Support Oracle global temporary transaction tables.

    Create a session-level global temporary table.

      CREATE GLOBAL TEMPORARY TABLE gtt_session(id number,ename varchar(15)) ON COMMIT PRESERVE ROWS;
      

    Create a transaction-level global temporary table.

      CREATE GLOBAL TEMPORARY TABLE gtt_transaction(id number,ename varchar(15)) ON COMMIT DELETE ROWS;
      

  • Automatically create a user with the same name as the database, and the automatically created user with the same name has create, connect, temporary, login permissions in the created database, and this function cannot be used in distributed systems. see CREATE DATABASE.

    lightdb@postgres=# create database testdb with lightdb_syntax_compatible_type oracle;
    NOTICE:  auto create user "testdb" success
    CREATE DATABASE
    
  • When the length of the variable type declaration can be supported, it can be supported in characters or bytes, and when the unit is currently characters, only syntax is supported. see orafce.

        create table hs_es(id int, name varchar2(10 byte));
        create table hs_lt(id int, name varchar2(10 char));
       
  • Added import tool ltldr, compatible with sqlldr tool. By importing data from a specified table into the database through a control file, multiple tables can be imported at the same time. For businesses that use sqlldr tools to import data, there are innate advantages.

  • Compatible with DBMS_UTILITY built-in package format_error_backtrace function, only record the latest record of the PlorasSQL execution error, use this function to view the location of the error. see support DBMS_UTILITY built-in package format_error_backtrace.

    Use function of DBMS_UTILITY.format_error_backtrace, for example:

    create or replace procedure pr_error_code_test1 is
        v_backtrace    varchar(1000);
        v_error        varchar(1000); 
    begin
    
        INSERT INTO test_error_stack values (2);
        INSERT INTO test_error_stack values (1);
        commit;
        exception when others then
        insert into t_errlog(operate_error_msg) select to_char(DBMS_UTILITY.format_error_backtrace);
        commit;
        rollback;
        end pr_error_code_test1;
    /
    
    select select to_char(DBMS_UTILITY.format_error_backtrace)
        

  • pl/sql supports stored procedures to use both return parameters with out decoration and return returns as null. The return null function is to abort the stored procedure. see Returning from a Procedure.

    create or replace procedure p_fmt_post_update_cash
    (
      p_src_system  varchar2 DEFAULT '0',
      p_init_date   number DEFAULT 0, 
      p_company_no  varchar2 DEFAULT '0',
      o_return_msg  out varchar2, 
      o_return_code out integer
    ) as
      v_init_date         int := 0;
    begin
      if v_init_date = 0 then
        o_return_code := 1;
        o_return_msg  := '请输入正确的校验日期';
    	return;
      end if;
     end;
    /