61.4. 版本发布 13.8-23.3

61.4.1. Oracle 兼容
61.4.2. pl/sql 增强
61.4.3. MySQL 兼容
61.4.4. lightdb 新特性
61.4.5. ltjdbc 增强

版本发布日期:. 2023年9月30日

61.4.1. Oracle 兼容

  • CREATE SEQUENCE 命令创建序列时支持声明 NOMAXVALUE,兼容Oracle创建序列时 NOMAXVALUE 定义。请参见 CREATE SEQUENCE

    示例:

    create sequence s1 nomaxvalue;
    \d+ s1
                                Sequence "public.s1"
    Type  | Start | Minimum |       Maximum       | Increment | Cycles? | Cache
    --------+-------+---------+---------------------+-----------+---------+-------
    bigint |     1 |       1 | 9223372036854775807 |         1 | no      |     1
                    
  • CREATE SEQUENCE 命令创建序列时支持声明 MAXVALUE,兼容Oracle创建序列时 MAXVALUE 定义。请参见 CREATE SEQUENCE

    示例:

    create sequence s2 maxvalue 100000;
    \d+ s2
    Sequence "public.s2"
    Type  | Start | Minimum | Maximum | Increment | Cycles? | Cache
    --------+-------+---------+---------+-----------+---------+-------
    bigint |     1 |       1 |  100000 |         1 | no      |     1
                    
  • CREATE TABLE 命令创建分区时支持 nocompress/compress 关键字。请参见 CREATE TABLE

    示例:

    CREATE TABLE lt_oracle_partition_list1
    (
        a int,
        b float,
        c date,
        d timestamp,
        e varchar2(20)
    ) PARTITION BY LIST(e)
    (
        PARTITION p1 VALUES ('0001', '0002', '0003', '0004', '0005') compress,
        PARTITION p2 VALUES ('0006', '0007', '0008', '0009') nocompress,
        PARTITION p3 VALUES ('0010', '0011')
    );
    \d+ lt_oracle_partition_list1
    
    Partitioned table "public.lt_oracle_partition_list1"
    Column |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
    --------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
    a      | integer                     |           |          |         | plain    |              |
    b      | double precision            |           |          |         | plain    |              |
    c      | oracle.date                 |           |          |         | plain    |              |
    d      | timestamp without time zone |           |          |         | plain    |              |
    e      | varchar2(20)                |           |          |         | extended |              |
    Partition key: LIST (e)
    Partitions: "lt_oracle_partition_list1$p$p1" FOR VALUES IN ('0001', '0002', '0003', '0004', '0005'),
    "lt_oracle_partition_list1$p$p2" FOR VALUES IN ('0006', '0007', '0008', '0009'),
    "lt_oracle_partition_list1$p$p3" FOR VALUES IN ('0010', '0011')
                    
  • CREATE TABLE 命令创建分区时支持 list+hash 复合分区。请参见 CREATE TABLE

    示例:

    create table lt_lh_partition(a int, b int)
    partition by list(a)
    subpartition by hash(b)
    (
        partition l_1 values(1),
        partition l_2 values(2)
    );
    
    \d+ lt_lh_partition
    
    Partitioned table "public.lt_lh_partition"
    Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
    --------+---------+-----------+----------+---------+---------+--------------+-------------
    a      | integer |           |          |         | plain   |              |
    b      | integer |           |          |         | plain   |              |
    Partition key: LIST (a)
    Partitions: "lt_lh_partition$p$l_1" FOR VALUES IN (1), PARTITIONED,
    "lt_lh_partition$p$l_2" FOR VALUES IN (2), PARTITIONED
    
    \d+ lt_lh_partition$p$l_1
    
    Partitioned table "public.lt_lh_partition$p$l_1"
    Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
    --------+---------+-----------+----------+---------+---------+--------------+-------------
    a      | integer |           |          |         | plain   |              |
    b      | integer |           |          |         | plain   |              |
    Partition of: lt_lh_partition FOR VALUES IN (1)
    Partition constraint: ((a IS NOT NULL) AND (a = 1))
    Partition key: HASH (b)
    Partitions: "lt_lh_partition$p$l_1_p0" FOR VALUES WITH (modulus 1, remainder 0)
                    
  • CREATE TABLE 命令支持了一些选项,如compress/nocompress,logging/nologging。 这些选项在历史版本使用上有顺序限制,该版本允许这些选项可以任意顺序出现。请参见 CREATE TABLE

  • 禁止 CREATE TABLE 创建的表名和 CREATE PACKAGE 创建的包名重复。

  • ALTER TABLE 命令支持一次添加多列时可以把列定义放在要括号里。请参见 ALTER TABLE

    示例:

    CREATE TABLE foo(a int);
    ALTER TABLE foo ADD COLUMN a1 int;
    ALTER TABLE foo ADD COLUMN a2 int default 3;
    ALTER TABLE foo ADD COLUMN b1 int, ADD COLUMN b2 int;
    ALTER TABLE foo ADD (c1 int);
    ALTER TABLE foo ADD (c2 int default 3);
    ALTER TABLE foo ADD (e1 int), ADD e2 int, ADD COLUMN e3 int, ADD (e4 int, e5 int);
    begin
        execute immediate 'alter table foo add(d int)';
    end;
    /
                    
  • ALTER TABLE 命令支持 TRUNCATE PARTITION partition_name 时指定 update indexes。请参见 ALTER TABLE

    示例:

    create table part_update_indexes_range(id int primary key)
    PARTITION by range(id)(
        partition p1 VALUES LESS THAN (202000) nocompress,
        partition p2 VALUES LESS THAN (202001) compress,
        partition p3 VALUES LESS THAN (202002)
    );
    
    ALTER  TABLE  part_update_indexes_range  TRUNCATE  PARTITION  p1 update indexes;
                    
  • DROP TABLE 命令支持通过 cascade constraints 级联删除该表所有的约束。请参见 DROP TABLE

    示例:

    CREATE TABLE student(id int, name varchar2(100));
    
    ALTER TABLE student ADD CONSTRAINT uk_student unique(id);
    
    \d student
    Table "public.student"
    Column |     Type      | Collation | Nullable | Default
    --------+---------------+-----------+----------+---------
    id     | integer       |           |          |
    name   | varchar2(100) |           |          |
    Indexes:
    "uk_student" UNIQUE CONSTRAINT, btree (id)
    
    DROP TABLE student cascade constraints;
                    
  • 新增 CREATE TYPE name { AS | IS } OBJECT 语法,支持创建对象类型。请参见 CREATE TYPE

    示例:

    select dbms_output.serveroutput(true);
    CREATE TYPE stock AS OBJECT (
        stock_no int,
        price    numeric(16,2),
        member procedure dis(prompt varchar)
    );
    
    CREATE TYPE BODY stock AS
    member procedure dis(prompt varchar) is
        begin
            dbms_output.put_line(prompt || ':' || self.stock_no || '-' || self.price);
        end;
    END;
    /
    
    DECLARE
        s stock := stock(600570, 180.00);
    BEGIN
        s.dis('current');
    END;
    /
    
    current:600570-180.00
    DO
                    
  • 新增 TO_CLOB 函数,通过该函数我们将能够将数据从文本字符串类型转换为 CLOB 类型。请参见 orafce

    示例:

    CREATE TABLE testorafce_to_clob (
        col_char CHAR(10),
        col_varchar2 VARCHAR2(20),
        col_varchar VARCHAR(20),
        col_nchar NCHAR(10),
        col_nvarchar2 NVARCHAR2(20),
        col_smallint smallint,
        col_integer integer,
        col_bigint bigint,
        col_decimal decimal,
        col_numeric numeric,
        col_real real,
        col_double double precision,
        col_clob CLOB,
        col_raw raw(10)
    );
    
    INSERT INTO testorafce_to_clob (col_char, col_varchar2, col_varchar, col_nchar, col_nvarchar2, col_smallint, col_integer, col_bigint, col_decimal, col_numeric, col_real, col_double, col_clob, col_raw)
    VALUES ('ABC1', 'Hello', 'world', 'hello', 'world', 1, 2, 3, 4, 5, 6, 7, 'This is a CLOB', 'AB');
    
    INSERT INTO testorafce_to_clob (col_char, col_varchar2, col_varchar, col_nchar, col_nvarchar2, col_smallint, col_integer, col_bigint, col_decimal, col_numeric, col_real, col_double, col_clob, col_raw)
    VALUES ('ABC2', 'Hello', 'world', 'hello', 'world', 1, 2, 3, 4, 5, 6, 7, 'This is a CLOB', '1');
    
    INSERT INTO testorafce_to_clob (col_char, col_varchar2, col_varchar, col_nchar, col_nvarchar2, col_smallint, col_integer, col_bigint, col_decimal, col_numeric, col_real, col_double, col_clob, col_raw)
    VALUES ('ABC3', 'Hello', 'world', 'hello', 'world', 1, 2, 3, 4, 5, 6, 7, to_clob('This is a CLOB'), '1AB456789');
    
    SELECT  to_clob(col_char) AS clob_char,
            to_clob(col_varchar2) AS clob_varchar2,
            to_clob(col_varchar) AS col_varchar,
            to_clob(col_nchar) AS clob_nchar,
            to_clob(col_nvarchar2) AS clob_nvarchar2,
            to_clob(col_clob) AS clob_clob,
            to_clob(col_smallint) AS col_smallint,
            to_clob(col_integer) AS col_integer,
            to_clob(col_bigint) AS col_bigint,
            to_clob(col_decimal) AS col_decimal,
            to_clob(col_numeric) AS col_numeric,
            to_clob(col_real) AS col_real,
            to_clob(col_double) AS col_double,
            to_clob(col_raw) AS clob_nclob
    FROM testorafce_to_clob order by col_char asc;
    
    clob_char  | clob_varchar2 | col_varchar | clob_nchar | clob_nvarchar2 |   clob_clob    | col_smallint | col_integer | col_bigint | col_decimal | col_numeric | col_real | col_double | clob_nclob
    ------------+---------------+-------------+------------+----------------+----------------+--------------+-------------+------------+-------------+-------------+----------+------------+------------
    ABC1       | Hello         | world       | hello      | world          | This is a CLOB | 1            | 2           | 3          | 4           | 5           | 6        | 7          | AB
    ABC2       | Hello         | world       | hello      | world          | This is a CLOB | 1            | 2           | 3          | 4           | 5           | 6        | 7          | 01
    ABC3       | Hello         | world       | hello      | world          | This is a CLOB | 1            | 2           | 3          | 4           | 5           | 6        | 7          | 01AB456789
    (3 rows)
                    
  • 新增 XMLType 对象类型,支持 XMLType.getClobVal 方法。请参见 orafce

    示例:

    
    CREATE TABLE xml_table (id NUMBER, xml_column XMLType );
    
    INSERT INTO xml_table (id, xml_column) VALUES (1, XMLType('<root><name>John</name></root>'));
    
    DECLARE
        v_clob CLOB;
    BEGIN
        SELECT XMLType.getClobVal(xml_column) INTO v_clob FROM xml_table WHERE id = 1;
        DBMS_OUTPUT.PUT_LINE('CLOB value: ' || v_clob);
    END;
    /
    CLOB value: <root><name>John</name></root>
    DO
    
    DECLARE
        xml_data XMLType;
        clob_data CLOB;
    BEGIN
        xml_data := XMLType('<root><name>John Doe</name></root>');
        clob_data := xml_data.getClobVal();
        DBMS_OUTPUT.PUT_LINE(clob_data);
    END;
    /
    <root><name>John Doe</name></root>
    DO
    
    SELECT XMLType.getClobVal(xml_column) from xml_table;
    getclobval
    --------------------------------
    <root><name>John</name></root>
    (1 row)
    
                    
  • 新增 lightdb_oracle_sql_mode GUC参数,用于支持Oracle模式下列名显示默认转为大写。请参见 lightdb_oracle_sql_mode

    示例:

    create table std(no int, name varchar2(32));
    
    insert into std values(1, 'zhangsan');
    
    select * from std;
    no |   name
    ----+----------
    1 | zhangsan
    (1 row)
    
    set lightdb_oracle_sql_mode to 'true';
    
    select * from std;
    NO |   NAME
    ----+----------
    1 | zhangsan
    (1 row)
                    
  • ltsql 命令新增支持Oracle SQL*Plus的 RENAME old_name TO new_name 命令,可以对表名进行重命名。请参见 RENAME 命令

  • ltsql 命令新增支持Oracle SQL*Plus SPOOL命令。请参见 SPOOL 命令

  • Oracle模式下支持 binary_floatbinary_double,都遵循IEEE754标准。请参见 orafce

  • Oracle模式下支持 '\0' 可以正常插入 char(n) 类型字符串中。

    示例:

    create database oradb with lightdb_ascii_zero_store_value 20 lightdb_syntax_compatible_type 'oracle';
    \c oradb
    
    create table t00(a char(1), b char(2));
    
    insert into t00(a,b) values(E'\0',E'\0');
    
    insert into t00(a,b) values(chr(0),chr(0));
    
    select * from t00;
    
    a   |   b
    ------+-------
    \x14 | \x14
    \x14 | \x14
    (2 rows)
    
    '\0' 转为了lightdb_ascii_zero_store_value值进行存储
                    
  • Oracle模式下日期作差结果兼容Oracle,返回numeric类型。

  • col视图兼容Oracle,width字段与Oracle保持兼容。

  • greatest/least兼容Oracle。请参见 GREATEST和LEAST

    主要实现了以下兼容特性:

    只要有一个参数为 NULL 结果就返回 NULL。

    把第一个参数作为被比较的类型,其余参数类型强制转换为第一个参数的类型。

    当遇到一个参数为 NULL 时,不再解析其余参数。

  • orafce 中的所有Oracle函数改成默认safe的,默认支持启用并行处理。

61.4.2. pl/sql 增强

  • pl/sql 函数支持事务提交回滚。请参见 针对Oracle的增强功能

  • pl/sql 函数支持 inout 参数。请参见 声明函数参数

  • pl/sql 函数支持DML语句。请参见 pl/sql中执行DML

  • pl/sql 存储过程中支持使用CREATE DOMAIN创建游标类型的变量。

    示例:

    SELECT dbms_output.serveroutput(true);
    CREATE TABLE employees(employee_id int, first_name varchar2(100), last_name varchar2(100));
    INSERT INTO employees values(1500, 'first15', 'last15');
    CREATE DOMAIN mycursor AS refcursor;
    CREATE OR REPLACE PROCEDURE get_employee_name AS
        employee_cursor mycursor;
        v_employee_name VARCHAR2(50);
    BEGIN
        OPEN employee_cursor FOR SELECT first_name FROM employees WHERE employee_id = 1500;
        LOOP
            FETCH employee_cursor INTO v_employee_name;
            EXIT WHEN employee_cursor%NOTFOUND;
            DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_employee_name);
        END LOOP;
        CLOSE employee_cursor;
    END;
    /
    call get_employee_name ();
    Employee Name: first15
    CALL
    
                    

61.4.3. MySQL 兼容

  • 新增 INSERT IGNORE 功能。 请参见 INSERT

    示例:

    create database test_mysql with lightdb_syntax_compatible_type  mysql;
    \c test_mysql
    
    create table t(a int primary key, b int);
    insert ignore into t(a,b) values(1,1),(1,1),(2,2);
    select * from t;
    a | b
    ---+---
    1 | 1
    2 | 2
    (2 rows)
                    
  • 新增 INSERT 支持对自增列插入NULL语法,每次插入都会根据序列进行自增。 请参见 INSERT NULL说明

  • 新增 JSON 函数集合。 请参见 MySQL兼容函数 JSON函数 。 函数清单如下:

    JSON_ARRAY

    JSON_OBJECT

    JSON_EXTRACT

    JSON_CONTAINS

    JSON_CONTAINS_PATH

    JSON_PRETTY

    JSON_REMOVE

    JSON_INSERT

    JSON_REPLACE

    JSON_SET

  • 新增 lightdb_mysql_lower_case_table_names 参数。 使用 create database 语句创建数据库时,可以指定参数来设置是否开启大小写敏感功能。 请参见 CREATE DATABASE

  • varchar 类型兼容 boolean 类型数据。 请参见 MySQL兼容函数

61.4.4. lightdb 新特性

  • 新增 lt_upgrade_check 升级前检查工具,用于提前检查升级不兼容及异常项,尽量避免在升级过程中出现失败。请参见 lt_upgrade_check

  • 新增 ECPG(Oracle Pro*c兼容) 代码中支持使用 ‘–’‘//’ 注释。 请参见 ECPG(Oracle Pro*c兼容)

  • 新增服务端、客户端支持GBK,GB18030-2022,已通过人行国标认证。 请参见 本地化

  • 新增 lt_createdb 行为在CN分布式下默认传播到DN节点。 请参见 lt_createdb

  • 新增 lightdb_cursor_after_commit GUC参数来控制fetch行为。 lightdb_cursor_after_commitoff 时不能在一个事务提交之后再去 fetch操作这个结果集; 为 on 时一个事务提交之后,这个游标还可以继续使用。 请参见 lightdb_cursor_after_commit

  • 新增 distinct connect by level 语法支持。

  • 新增 connect_by_isleaf 语法支持。 请参见 SELECT

  • ltsql 增强支持提示当前服务数据库的兼容模式。

  • lt_upgrade 增强支持跨版本升级。

  • ltloader 增强性能,达到Oracle sqlldr的80%以上。 请参见 ltldr

  • lt_dump 增强。 请参见 lt_dump 。 清单如下:

    --lt-exclude-lightdb-objects 支持过滤内置用户 lightdblt_probackup

    --lt-exclude-lightdb-objects 支持导出 ACCESS METHOD

    lt_dumplt_dumpall 增加 --lt-target-version 选项,用于指定导出的内容所适用的目标版本。

    导出默认的创建模版支持为 template1

    create database 语句支持 lightdb_syntax_compatible_type 选项逻辑。

  • mysql_fdw 增强支持查询超过64K的字段。

61.4.5. ltjdbc 增强

  • ltjdbc 支持 numeric 使用 Short 类型。

  • ltjdbc 支持setNull传入 Types.CLOBTypes.BLOB

  • ltjdbc 支持整型数值使用 string 类型。

  • ltjdbc 支持函数 xmlparse