ef6ad6d8创建于 2023年3月21日历史提交
DROP SCHEMA IF EXISTS srf_fusion_basic CASCADE;
NOTICE:  schema "srf_fusion_basic" does not exist, skipping
CREATE SCHEMA srf_fusion_basic;
SET search_path = srf_fusion_basic;
------------------------------------------
-- sqlbypass_partition BEGIN
SET enable_expr_fusion = on;
SHOW enable_expr_fusion;
 enable_expr_fusion 
--------------------
 on
(1 row)

set enable_opfusion=on;
set enable_partition_opfusion=on;
set enable_bitmapscan=off;
set enable_seqscan=off;
set opfusion_debug_mode = 'log';
set log_min_messages=debug;
set logging_module = 'on(OPFUSION)';
set sql_beta_feature = 'index_cost_with_leaf_pages_only';
--create table
drop table if exists test_bypass_sql_partition;
NOTICE:  table "test_bypass_sql_partition" does not exist, skipping
create table test_bypass_sql_partition(col1 int, col2 int, col3 text)
partition by range (col1)
(
partition test_bypass_sql_partition_1 values less than(10),
partition test_bypass_sql_partition_2 values less than(20),
partition test_bypass_sql_partition_3 values less than(30),
partition test_bypass_sql_partition_4 values less than(40),
partition test_bypass_sql_partition_5 values less than(50),
partition test_bypass_sql_partition_6 values less than(60),
partition test_bypass_sql_partition_7 values less than(70),
partition test_bypass_sql_partition_8 values less than(80)
);
create index itest_bypass_sql_partition on test_bypass_sql_partition(col1,col2) local;
--nobypass
explain insert into test_bypass_sql_partition values(0,generate_series(1,100),'test');
                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 [No Bypass]reason: Bypass not executed because query combines insert operator with others.
 Insert on test_bypass_sql_partition  (cost=0.00..7.52 rows=1000 width=40)
   ->  ProjectSet  (cost=0.00..7.52 rows=1000 width=40)
         ->  Result  (cost=0.00..0.01 rows=1 width=0)
(4 rows)

insert into test_bypass_sql_partition values(0,generate_series(1,100),'test');
RESET enable_opfusion;
RESET enable_partition_opfusion;
RESET enable_bitmapscan;
RESET enable_seqscan;
RESET opfusion_debug_mode;
RESET log_min_messages;
RESET logging_module;
RESET sql_beta_feature;
-- sqlbypass_partition END
------------------------------------------
-- single_node_union BEGIN
SET enable_expr_fusion = on;
SHOW enable_expr_fusion;
 enable_expr_fusion 
--------------------
 on
(1 row)

-- Test that we push quals into UNION sub-selects only when it's safe
set query_dop = 1;
explain (verbose, costs off)
SELECT * FROM
  (SELECT 1 AS t, generate_series(1,10) AS x
   UNION
   SELECT 2 AS t, 4 AS x) ss
WHERE x < 4
ORDER BY x;
                         QUERY PLAN                          
-------------------------------------------------------------
 Sort
   Output: ss.t, ss.x
   Sort Key: ss.x
   ->  Subquery Scan on ss
         Output: ss.t, ss.x
         Filter: (ss.x < 4)
         ->  HashAggregate
               Output: (1), (generate_series(1, 10))
               Group By Key: (1), (generate_series(1, 10))
               ->  Append
                     ->  ProjectSet
                           Output: 1, generate_series(1, 10)
                           ->  Result
                     ->  Result
                           Output: 2, 4
(15 rows)

SELECT * FROM
  (SELECT 1 AS t, generate_series(1,10) AS x
   UNION
   SELECT 2 AS t, 4 AS x) ss
WHERE x < 4
ORDER BY x;
 t | x 
---+---
 1 | 1
 1 | 2
 1 | 3
(3 rows)

-- Test that single node stream plan handles UNION sub-selects correctly
set query_dop = 10; -- srf dont support this, so there is no ProjectSet in plan
explain (verbose, costs off)
SELECT * FROM
  (SELECT 1 AS t, generate_series(1,10) AS x
   UNION
   SELECT 2 AS t, 4 AS x) ss
WHERE x < 4
ORDER BY x;
                         QUERY PLAN                          
-------------------------------------------------------------
 Sort
   Output: ss.t, ss.x
   Sort Key: ss.x
   ->  Subquery Scan on ss
         Output: ss.t, ss.x
         Filter: (ss.x < 4)
         ->  HashAggregate
               Output: (1), (generate_series(1, 10))
               Group By Key: (1), (generate_series(1, 10))
               ->  Append
                     ->  Result
                           Output: 1, generate_series(1, 10)
                     ->  Result
                           Output: 2, 4
(14 rows)

SELECT * FROM
  (SELECT 1 AS t, generate_series(1,10) AS x
   UNION
   SELECT 2 AS t, 4 AS x) ss
WHERE x < 4
ORDER BY x;
 t | x 
---+---
 1 | 1
 1 | 2
 1 | 3
(3 rows)

RESET query_dop;
-- single_node_union END
------------------------------------------
-- merge_where_col BEGIN
SET enable_expr_fusion = on;
SHOW enable_expr_fusion;
 enable_expr_fusion 
--------------------
 on
(1 row)

--
-- MERGE INTO 
--
-- part 1
-- initial
DROP SCHEMA IF EXISTS srf_fusion_merge_where_col;
NOTICE:  schema "srf_fusion_merge_where_col" does not exist, skipping
CREATE SCHEMA srf_fusion_merge_where_col;
SET current_schema = srf_fusion_merge_where_col;
drop table if exists merge_nest_tab1,dt2;
NOTICE:  table "merge_nest_tab1" does not exist, skipping
NOTICE:  table "dt2" does not exist, skipping
create table merge_nest_tab1(co1 numeric(20,4),co2 varchar2,co3 number,co4 date);
insert into merge_nest_tab1 values(generate_series(1,10),'hello'||generate_series(1,10),generate_series(1,10)*10,sysdate);
create table dt2(c1 numeric(20,4),c2 boolean,c3 character(40),c4 binary_double,c5 nchar(20)) WITH (ORIENTATION = COLUMN);
insert into dt2 values(generate_series(20,50),false,generate_series(20,50)||'gauss',generate_series(20,50)-0.99,'openopen');
-- we can't use columns of target table in insertion subquery(co1<45) for 'where'
BEGIN; 
merge into merge_nest_tab1 a
USING dt2 b
    ON a.co1=b.c1-20
    WHEN NOT matched THEN
    insert(co1,co2,co3) values(100,
    (SELECT 666)||'good',
        (SELECT sum(c.c1)
        FROM dt2 c
        INNER JOIN merge_nest_tab1 d
            ON c.c1=d.co1 ))
    WHERE co1<45;
ERROR:  column "co1" does not exist
LINE 11:     WHERE co1<45;
                   ^
HINT:  There is a column named "co1" in table "a", but it cannot be referenced from this part of the query.
END; 
-- we can use columns of source table in insertion subquery(c1<45) for 'where'
BEGIN; 
merge into merge_nest_tab1 a
USING dt2 b
    ON a.co1=b.c1-20
    WHEN NOT matched THEN
    insert(co1,co2,co3) values(100,
    (SELECT 666)||'good',
        (SELECT sum(c.c1)
        FROM dt2 c
        INNER JOIN merge_nest_tab1 d
            ON c.c1=d.co1 ))
    WHERE c1<45;
SELECT co1, co2, co3 FROM merge_nest_tab1 order by 1; 
   co1    |   co2   | co3 
----------+---------+-----
   1.0000 | hello1  |  10
   2.0000 | hello2  |  20
   3.0000 | hello3  |  30
   4.0000 | hello4  |  40
   5.0000 | hello5  |  50
   6.0000 | hello6  |  60
   7.0000 | hello7  |  70
   8.0000 | hello8  |  80
   9.0000 | hello9  |  90
  10.0000 | hello10 | 100
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
 100.0000 | 666good |    
(25 rows)

ROLLBACK; 
-- we can use columns of source table in insert subquery(c1<45) for 'where'
BEGIN; 
merge into merge_nest_tab1 a
USING dt2 b
    ON a.co1=b.c1-20
    WHEN matched THEN
        UPDATE SET a.co3=a.co3 + b.c4,
         a.co2='hello',
         a.co4=(SELECT last_day(sysdate))
    WHERE c1 BETWEEN 1 AND 50;
SELECT co1, co2, co3 FROM merge_nest_tab1 order by 1; 
   co1   |  co2  |  co3   
---------+-------+--------
  1.0000 | hello |  30.01
  2.0000 | hello |  41.01
  3.0000 | hello |  52.01
  4.0000 | hello |  63.01
  5.0000 | hello |  74.01
  6.0000 | hello |  85.01
  7.0000 | hello |  96.01
  8.0000 | hello | 107.01
  9.0000 | hello | 118.01
 10.0000 | hello | 129.01
(10 rows)

ROLLBACK; 
-- part 2
-- initial
drop table if exists tb_a,tb_b;
NOTICE:  table "tb_a" does not exist, skipping
NOTICE:  table "tb_b" does not exist, skipping
create table tb_a(id int, a int, b int, c int, d int);
create table tb_b(id int, a int, b int, c int, d int);
insert into tb_a values(1, 1, 1, 1, 1);
insert into tb_a values(2, 2, 2, 2, 2);
insert into tb_a values(3, 3, 3, 3, 3);
insert into tb_a values(4, 4, 4, 4, 4);
insert into tb_b values(1, 100, 1, 1, 1);
insert into tb_b values(2, 2, 2, 2, 2);
insert into tb_b values(3, 3, 3, 3, 3);
insert into tb_b values(4, 4, 4, 4, 4);
-- if the column has the same name, the column in the target table takes precedence
BEGIN; 
MERGE INTO tb_b bt
USING tb_a at
    ON (at.id = bt.id)
    WHEN MATCHED THEN
    UPDATE SET a = at.a + 100 WHERE a =100;
SELECT * FROM tb_b ORDER BY  1; 
 id |  a  | b | c | d 
----+-----+---+---+---
  1 | 101 | 1 | 1 | 1
  2 |   2 | 2 | 2 | 2
  3 |   3 | 3 | 3 | 3
  4 |   4 | 4 | 4 | 4
(4 rows)

ROLLBACK; 
create table col_com_base_1(
col_int                      integer,
col_double                   double precision,
col_date                     date
);
create table col_com_base_2(
col_int                      integer,
col_double                   double precision,
col_date                     date
);
MERGE INTO col_com_base_1 Table_004 USING col_com_base_2 Table_003
    ON ( Table_003.col_double = Table_004.col_double ) 
WHEN MATCHED THEN UPDATE SET col_date = col_date
WHERE  Table_004.col_int = ( select SUM(Table_004.col_int) from col_com_base_1);
ERROR:  aggregate functions are not allowed in MERGE WHEN conditions
LINE 4: WHERE  Table_004.col_int = ( select SUM(Table_004.col_int) f...
                                            ^
CONTEXT:  referenced column: sum
UPDATE col_com_base_1 Table_004 SET col_int = 2 where Table_004.col_int = ( select SUM(Table_004.col_int) from col_com_base_1);
ERROR:  aggregate functions are not allowed in WHERE
LINE 1: ...ET col_int = 2 where Table_004.col_int = ( select SUM(Table_...
                                                             ^
CONTEXT:  referenced column: sum
UPDATE col_com_base_1 Table_004 SET col_int = 2 where Table_004.col_int = ( select SUM(col_int) from col_com_base_1);
-- clean up
DROP SCHEMA srf_fusion_merge_where_col CASCADE;
NOTICE:  drop cascades to 6 other objects
DETAIL:  drop cascades to table merge_nest_tab1
drop cascades to table dt2
drop cascades to table tb_a
drop cascades to table tb_b
drop cascades to table col_com_base_1
drop cascades to table col_com_base_2
-- merge_where_col END;
------------------------------------------
-- multi_update BEGIN
create database multiupdate DBCOMPATIBILITY = 'B';
\c multiupdate;
\h update
Command:     UPDATE
Description: update rows of a table
Syntax:
UPDATE Single-Relation Syntax:
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [/*+ plan_hint */] [ ONLY ] table_name [ partition_clause ] [ * ] [ [ AS ] alias ]
SET {column_name = { expression | DEFAULT } 
    |( column_name [, ...] ) = {( { expression | DEFAULT } [, ...] ) |sub_query }}[, ...]
    [ FROM from_list] [ WHERE condition ]
    [ ORDER BY {expression [ [ ASC | DESC | USING operator ]
    [ LIMIT { count } ]
    [ RETURNING {* | {output_expression [ [ AS ] output_name ]} [, ...] }];

UPDATE Multiple-Relation Syntax:
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [/*+ plan_hint */] table_list
SET {column_name = { expression | DEFAULT } 
    |( column_name [, ...] ) = {( { expression | DEFAULT } [, ...] ) |sub_query }}[, ...]
    [ FROM from_list] [ WHERE condition ];

where sub_query can be:
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
{ * | {expression [ [ AS ] output_name ]} [, ...] }
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY grouping_element [, ...] ]
[ HAVING condition [, ...] ]
where partition_clause can be:
PARTITION { ( partition_name ) | FOR ( partition_value [, ...] ) } |
SUBPARTITION { ( subpartition_name ) | FOR ( subpartition_value [, ...] ) }
NOTICE: UPDATE Multiple-Relation Syntax is only avaliable in CENTRALIZED mode and B-format database!
NOTICE: 'partition_clause' is only avaliable in CENTRALIZED mode!

SET enable_expr_fusion = on;
SHOW enable_expr_fusion;
 enable_expr_fusion 
--------------------
 on
(1 row)

-- three relation
drop table if exists t_t_mutil_t1;
NOTICE:  table "t_t_mutil_t1" does not exist, skipping
drop table if exists t_t_mutil_t2;
NOTICE:  table "t_t_mutil_t2" does not exist, skipping
drop table if exists t_t_mutil_t3;
NOTICE:  table "t_t_mutil_t3" does not exist, skipping
create table t_t_mutil_t1(col1 int,col2 int);
create table t_t_mutil_t2(col1 int,col2 int);
create table t_t_mutil_t3(col1 int,col2 int);
insert into t_t_mutil_t1 values(1,1),(1,1);
insert into t_t_mutil_t2 values(1,1),(1,2);
insert into t_t_mutil_t3 values(1,1),(1,3);
begin;
update t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c set b.col2=5,a.col2=4,c.col2=6 where a.col1=b.col1 and b.col1=c.col1;
select * from t_t_mutil_t1;
 col1 | col2 
------+------
    1 |    4
    1 |    4
(2 rows)

select * from t_t_mutil_t2;
 col1 | col2 
------+------
    1 |    5
    1 |    5
(2 rows)

select * from t_t_mutil_t3;
 col1 | col2 
------+------
    1 |    6
    1 |    6
(2 rows)

update t_t_mutil_t1 a,t_t_mutil_t2 b set a.col2=7,b.col2=8 where a.col1=b.col1;
select * from t_t_mutil_t1;
 col1 | col2 
------+------
    1 |    7
    1 |    7
(2 rows)

select * from t_t_mutil_t2;
 col1 | col2 
------+------
    1 |    8
    1 |    8
(2 rows)

rollback;
-- subselect
begin;
update t_t_mutil_t1 a,t_t_mutil_t2 b set b.col2=5,a.col2=4 where a.col1 in (select col1 from t_t_mutil_t2);
rollback;
-- setof type, report error
update t_t_mutil_t1 a,t_t_mutil_t2 b set a.col1 = generate_series(2,3), b.col1=1;
ERROR:  set-returning functions are not allowed
LINE 1: update t_t_mutil_t1 a,t_t_mutil_t2 b set a.col1 = generate_s...
                                                          ^
CONTEXT:  referenced column: a
update t_t_mutil_t1 a,t_t_mutil_t2 b set b.col1 = generate_series(2,3), a.col1=1;
ERROR:  set-returning functions are not allowed
LINE 1: update t_t_mutil_t1 a,t_t_mutil_t2 b set b.col1 = generate_s...
                                                          ^
CONTEXT:  referenced column: b
update t_t_mutil_t1 a,t_t_mutil_t2 b set a.col1 = generate_series(2,3),b.col1 =123;
ERROR:  set-returning functions are not allowed
LINE 1: update t_t_mutil_t1 a,t_t_mutil_t2 b set a.col1 = generate_s...
                                                          ^
CONTEXT:  referenced column: a
\c regression
drop database multiupdate;
-- multi_update END
------------------------------------------
-- vec_set_func BEGIN
SET enable_expr_fusion = on;
SHOW enable_expr_fusion;
 enable_expr_fusion 
--------------------
 on
(1 row)

set enable_vector_engine=on;
create table hl_test002(a int,b varchar2(15), c varchar2(15)); 
insert into hl_test002 values(1,'gauss,ap', 'xue,dong,pu'); 
insert into hl_test002 values(1,'gauss,ap', NULL); 
insert into hl_test002 values(1,'xue,dong,pu', 'gauss,ap,db'); 
insert into hl_test002 values(1,'xue,dong,pu', NULL); 
insert into hl_test002 values(2,'xi,an', 'wang,,rui'); 
insert into hl_test002 values(2,'xi,an', NULL); 
insert into hl_test002 values(2,'wang,,rui', 'xi,an'); 
insert into hl_test002 values(2,'wang,,rui', NULL);
create table hl_test001(a int,b varchar2(15), c varchar2(15)) with (ORIENTATION = COLUMN); 
insert into hl_test001 select * from hl_test002;
create table hl_test003(a int,b int[5]) with (ORIENTATION = COLUMN);
insert into hl_test003 values(1, array[1,2,3]),(2,array[5,4,6]);
select a,b,c,regexp_split_to_table(b,E',') from hl_test001 order by 1, 2, 3, 4 nulls last;
 a |      b      |      c      | regexp_split_to_table 
---+-------------+-------------+-----------------------
 1 | gauss,ap    | xue,dong,pu | ap
 1 | gauss,ap    | xue,dong,pu | gauss
 1 | gauss,ap    |             | ap
 1 | gauss,ap    |             | gauss
 1 | xue,dong,pu | gauss,ap,db | dong
 1 | xue,dong,pu | gauss,ap,db | pu
 1 | xue,dong,pu | gauss,ap,db | xue
 1 | xue,dong,pu |             | dong
 1 | xue,dong,pu |             | pu
 1 | xue,dong,pu |             | xue
 2 | wang,,rui   | xi,an       | rui
 2 | wang,,rui   | xi,an       | wang
 2 | wang,,rui   | xi,an       | 
 2 | wang,,rui   |             | rui
 2 | wang,,rui   |             | wang
 2 | wang,,rui   |             | 
 2 | xi,an       | wang,,rui   | an
 2 | xi,an       | wang,,rui   | xi
 2 | xi,an       |             | an
 2 | xi,an       |             | xi
(20 rows)

select a,b,c,regexp_split_to_table(b,NULL) from hl_test001 order by 1, 2, 3, 4 nulls last;
 a | b | c | regexp_split_to_table 
---+---+---+-----------------------
(0 rows)

select a,b,c,regexp_split_to_table(b,E','), regexp_split_to_table(c,E',') from hl_test001 order by 1, 2, 3, 4, 5 nulls last;
 a |      b      |      c      | regexp_split_to_table | regexp_split_to_table 
---+-------------+-------------+-----------------------+-----------------------
 1 | gauss,ap    | xue,dong,pu | ap                    | dong
 1 | gauss,ap    | xue,dong,pu | ap                    | pu
 1 | gauss,ap    | xue,dong,pu | ap                    | xue
 1 | gauss,ap    | xue,dong,pu | gauss                 | dong
 1 | gauss,ap    | xue,dong,pu | gauss                 | pu
 1 | gauss,ap    | xue,dong,pu | gauss                 | xue
 1 | xue,dong,pu | gauss,ap,db | dong                  | ap
 1 | xue,dong,pu | gauss,ap,db | pu                    | db
 1 | xue,dong,pu | gauss,ap,db | xue                   | gauss
 2 | wang,,rui   | xi,an       | rui                   | an
 2 | wang,,rui   | xi,an       | rui                   | xi
 2 | wang,,rui   | xi,an       | wang                  | an
 2 | wang,,rui   | xi,an       | wang                  | xi
 2 | wang,,rui   | xi,an       |                       | an
 2 | wang,,rui   | xi,an       |                       | xi
 2 | xi,an       | wang,,rui   | an                    | rui
 2 | xi,an       | wang,,rui   | an                    | wang
 2 | xi,an       | wang,,rui   | an                    | 
 2 | xi,an       | wang,,rui   | xi                    | rui
 2 | xi,an       | wang,,rui   | xi                    | wang
 2 | xi,an       | wang,,rui   | xi                    | 
(21 rows)

explain (verbose, costs off)
select regexp_split_to_table(b,E','), generate_series(1, 3) from hl_test001;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 ProjectSet
   Output: regexp_split_to_table((b)::text, ','::text), generate_series(1, 3)
   ->  Row Adapter
         Output: b
         ->  CStore Scan on public.hl_test001
               Output: b
(6 rows)

select regexp_split_to_table(b,E','), generate_series(1, 3) from hl_test001;
 regexp_split_to_table | generate_series 
-----------------------+-----------------
 gauss                 |               1
 ap                    |               2
 gauss                 |               3
 ap                    |               1
 gauss                 |               2
 ap                    |               3
 gauss                 |               1
 ap                    |               2
 gauss                 |               3
 ap                    |               1
 gauss                 |               2
 ap                    |               3
 xue                   |               1
 dong                  |               2
 pu                    |               3
 xue                   |               1
 dong                  |               2
 pu                    |               3
 xi                    |               1
 an                    |               2
 xi                    |               3
 an                    |               1
 xi                    |               2
 an                    |               3
 xi                    |               1
 an                    |               2
 xi                    |               3
 an                    |               1
 xi                    |               2
 an                    |               3
 wang                  |               1
                       |               2
 rui                   |               3
 wang                  |               1
                       |               2
 rui                   |               3
(36 rows)

select a, b, unnest(b) from hl_test003;
 a |    b    | unnest 
---+---------+--------
 1 | {1,2,3} |      1
 1 | {1,2,3} |      2
 1 | {1,2,3} |      3
 2 | {5,4,6} |      5
 2 | {5,4,6} |      4
 2 | {5,4,6} |      6
(6 rows)

select a,b,c,regexp_split_to_table(regexp_split_to_table(b,E','), E'u') from hl_test001 order by 1, 2, 3, 4 nulls last;
 a |      b      |      c      | regexp_split_to_table 
---+-------------+-------------+-----------------------
 1 | gauss,ap    | xue,dong,pu | ap
 1 | gauss,ap    | xue,dong,pu | ga
 1 | gauss,ap    | xue,dong,pu | ss
 1 | gauss,ap    |             | ap
 1 | gauss,ap    |             | ga
 1 | gauss,ap    |             | ss
 1 | xue,dong,pu | gauss,ap,db | dong
 1 | xue,dong,pu | gauss,ap,db | e
 1 | xue,dong,pu | gauss,ap,db | p
 1 | xue,dong,pu | gauss,ap,db | x
 1 | xue,dong,pu | gauss,ap,db | 
 1 | xue,dong,pu |             | dong
 1 | xue,dong,pu |             | e
 1 | xue,dong,pu |             | p
 1 | xue,dong,pu |             | x
 1 | xue,dong,pu |             | 
 2 | wang,,rui   | xi,an       | i
 2 | wang,,rui   | xi,an       | r
 2 | wang,,rui   | xi,an       | wang
 2 | wang,,rui   |             | i
 2 | wang,,rui   |             | r
 2 | wang,,rui   |             | wang
 2 | xi,an       | wang,,rui   | an
 2 | xi,an       | wang,,rui   | xi
 2 | xi,an       |             | an
 2 | xi,an       |             | xi
(26 rows)

select a,b,c,substring(regexp_split_to_table(b,E','), 1, 100) from hl_test001 order by 1, 2, 3, 4 nulls last;
 a |      b      |      c      | substring 
---+-------------+-------------+-----------
 1 | gauss,ap    | xue,dong,pu | ap
 1 | gauss,ap    | xue,dong,pu | gauss
 1 | gauss,ap    |             | ap
 1 | gauss,ap    |             | gauss
 1 | xue,dong,pu | gauss,ap,db | dong
 1 | xue,dong,pu | gauss,ap,db | pu
 1 | xue,dong,pu | gauss,ap,db | xue
 1 | xue,dong,pu |             | dong
 1 | xue,dong,pu |             | pu
 1 | xue,dong,pu |             | xue
 2 | wang,,rui   | xi,an       | rui
 2 | wang,,rui   | xi,an       | wang
 2 | wang,,rui   | xi,an       | 
 2 | wang,,rui   |             | rui
 2 | wang,,rui   |             | wang
 2 | wang,,rui   |             | 
 2 | xi,an       | wang,,rui   | an
 2 | xi,an       | wang,,rui   | xi
 2 | xi,an       |             | an
 2 | xi,an       |             | xi
(20 rows)

select a,b,c,regexp_split_to_table(substring(b,1, 100), E',') from hl_test001 order by 1, 2, 3, 4 nulls last;
 a |      b      |      c      | regexp_split_to_table 
---+-------------+-------------+-----------------------
 1 | gauss,ap    | xue,dong,pu | ap
 1 | gauss,ap    | xue,dong,pu | gauss
 1 | gauss,ap    |             | ap
 1 | gauss,ap    |             | gauss
 1 | xue,dong,pu | gauss,ap,db | dong
 1 | xue,dong,pu | gauss,ap,db | pu
 1 | xue,dong,pu | gauss,ap,db | xue
 1 | xue,dong,pu |             | dong
 1 | xue,dong,pu |             | pu
 1 | xue,dong,pu |             | xue
 2 | wang,,rui   | xi,an       | rui
 2 | wang,,rui   | xi,an       | wang
 2 | wang,,rui   | xi,an       | 
 2 | wang,,rui   |             | rui
 2 | wang,,rui   |             | wang
 2 | wang,,rui   |             | 
 2 | xi,an       | wang,,rui   | an
 2 | xi,an       | wang,,rui   | xi
 2 | xi,an       |             | an
 2 | xi,an       |             | xi
(20 rows)

drop table hl_test001;
drop table hl_test002;
drop table hl_test003;
reset enable_vector_engine;
-- vec_set_func END
------------------------------------------