This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 67aef6b76b6 [feature]support unnest function (#3203)
67aef6b76b6 is described below

commit 67aef6b76b6f8bfb2b168b9cf0c792574cf61b01
Author: starocean999 <[email protected]>
AuthorDate: Tue Feb 10 08:04:31 2026 +0800

    [feature]support unnest function (#3203)
    
    ## Versions
    
    - [x] dev
    - [ ] 4.x
    - [ ] 3.x
    - [ ] 2.1
    
    ## Languages
    
    - [x] Chinese
    - [x] English
    
    ## Docs Checklist
    
    - [ ] Checked by AI
    - [ ] Test Cases Built
    
    https://github.com/apache/doris/pull/58228
---
 .../sql-functions/table-functions/unnest.md        | 208 +++++++++++++++++++++
 .../sql-functions/table-functions/unnest.md        | 208 +++++++++++++++++++++
 2 files changed, 416 insertions(+)

diff --git a/docs/sql-manual/sql-functions/table-functions/unnest.md 
b/docs/sql-manual/sql-functions/table-functions/unnest.md
new file mode 100644
index 00000000000..2621df9901a
--- /dev/null
+++ b/docs/sql-manual/sql-functions/table-functions/unnest.md
@@ -0,0 +1,208 @@
+---
+{
+    "title": "UNNEST",
+    "language": "en-US"
+}
+---
+
+## Description
+`unnest` expands array/collection/map type expressions into multiple rows (a 
table-generating function). It can be used in the SELECT list and FROM clause, 
and supports WITH ORDINALITY to append a sequence number to each expanded row. 
Similar to the `explode` series of functions, `unnest` supports multiple 
parameters, types such as Map and Bitmap, and also supports LEFT (outer) 
semantics in FROM/LATERAL and JOIN scenarios.
+
+## Syntax
+```sql
+UNNEST(<expr>[, ...]) [WITH ORDINALITY] [AS alias [(col1, col2, ...)]]
+-- LATERAL can be added before the FROM clause: LATERAL UNNEST(...), where 
LATERAL is an optional keyword
+```
+
+## Parameters
+- <expr>: Can be ARRAY, MAP, BITMAP, or a list of expressions (only ARRAY type 
is supported for multiple parameters).
+
+## Return Values
+- Single ARRAY parameter: Returns a single column with multiple rows of the 
element type (one row per element). If an element is NULL, NULL is output.
+- Multiple ARRAY parameters: Combines the elements expanded each time into 
multiple columns (or as a Struct) by position. The expansion length is 
determined by the longest input, and shorter columns are padded with NULL.
+- MAP parameter: Returns two columns (Struct) (key, value); NULL keys/values 
remain NULL.
+- BITMAP parameter: Returns integer values by element.
+- WITH ORDINALITY: Appends a sequence number column starting from 1 to the 
output (as the last column or specified by an alias).
+- Empty array or NULL:
+  - When generating an independent table (SELECT list or FROM ... UNNEST), if 
the parameter is NULL or an empty array, no rows are generated (0 rows).
+  - When used in combination with FROM/LATERAL and LEFT JOIN (i.e., generating 
outer row semantics), if all expanded rows of a parent row are filtered or have 
no output, a row is inserted for the parent row, with the UNNEST output columns 
set to NULL (to retain the left table row).
+
+## Usage Notes
+1. The parameter type must be ARRAY / MAP / BITMAP; otherwise, an error is 
thrown.
+2. When expanding multiple parameters, pairing is done by position; 
insufficient columns are padded with NULL.
+3. An alias can be used with AS to explicitly specify expanded column names; 
if no column names are specified, the system generates default column names.
+4. In JOIN scenarios:
+   - INNER / CROSS JOIN: Performs Cartesian product or matching based on the 
expanded results.
+   - LEFT JOIN LATERAL: Implements outer row semantics — if there are no 
matches or all expanded results are filtered by ON/filter conditions, a row 
with NULL values is generated (to retain the left table row).
+5. WITH ORDINALITY adds a sequence number (starting from 1) to the expanded 
rows.
+6. When UNNEST(...) is used directly in the SELECT list, it is equivalent to 
applying the table-generating function to a single-row source, expanding the 
expression into multiple rows of output.
+
+## Examples
+Preparation:
+```sql
+CREATE TABLE items (
+    id INT,
+    name VARCHAR(50),
+    tags ARRAY<VARCHAR(50)>, 
+    price DECIMAL(10,2),
+    category_ids ARRAY<INT>  
+) ENGINE=OLAP
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 10
+PROPERTIES (
+    "replication_allocation" = "tag.location.default: 1"
+);
+
+INSERT INTO items (id, name, tags, price, category_ids) VALUES
+        (1, 'Laptop', ['Electronics', 'Office', 'High-End', 'Laptop'], 
5999.99, [1, 2, 3]),
+        (2, 'Mechanical Keyboard', ['Electronics', 'Accessories'], 399.99, [1, 
2]),
+        (3, 'Basketball', ['Sports', 'Outdoor'], 199.99, [1,3]),
+        (4, 'Badminton Racket', ['Sports', 'Equipment'], 299.99, [3]),
+        (5, 'Shirt', ['Clothing', 'Office', 'Shirt'], 259.00, [4]);
+```
+1. Used in the SELECT list (single expression expanded into multiple rows):
+```sql
+SELECT unnest([1,2,3]);
+```
+Output (example):
+```sql
++-----------------+
+| unnest([1,2,3]) |
++-----------------+
+|               1 |
+|               2 |
+|               3 |
++-----------------+
+```
+2. Expansion in FROM / LATERAL with specified column names:
+```sql
+SELECT i.id, t.tag
+FROM items i, unnest(i.tags) AS t(tag)
+ORDER BY i.id, t.tag;
+```
+Output (example):
+```sql
++------+-------------+
+| id   | tag         |
++------+-------------+
+|    1 | Electronics |
+|    1 | High-End    |
+|    1 | Laptop      |
+|    1 | Office      |
+|    2 | Accessories |
+|    2 | Electronics |
+|    3 | Outdoor     |
+|    3 | Sports      |
+|    4 | Equipment   |
+|    4 | Sports      |
+|    5 | Clothing    |
+|    5 | Office      |
+|    5 | Shirt       |
++------+-------------+
+```
+3. WITH ORDINALITY:
+```sql
+SELECT i.id, t.ord, t.tag
+FROM items i, unnest(i.tags) WITH ORDINALITY AS t(tag, ord)
+ORDER BY i.id, t.ord;
+```
+Output (example):
+```sql
++------+-------------+------+
+| id   | ord         | tag  |
++------+-------------+------+
+|    1 | Electronics |    0 |
+|    1 | High-End    |    2 |
+|    1 | Laptop      |    3 |
+|    1 | Office      |    1 |
+|    2 | Accessories |    1 |
+|    2 | Electronics |    0 |
+|    3 | Outdoor     |    1 |
+|    3 | Sports      |    0 |
+|    4 | Equipment   |    1 |
+|    4 | Sports      |    0 |
+|    5 | Clothing    |    0 |
+|    5 | Office      |    1 |
+|    5 | Shirt       |    2 |
++------+-------------+------+
+```
+4. INNER JOIN to retain matching rows:
+```sql
+SELECT i.id, t.tag, i.name
+FROM items i
+INNER JOIN unnest(i.tags) AS t(tag) ON t.tag = i.name;
+```
+Output (example):
+```sql
++------+--------+--------+
+| id   | tag    | name   |
++------+--------+--------+
+|    1 | Laptop | Laptop |
+|    5 | Shirt  | Shirt  |
++------+--------+--------+
+```
+5. LEFT JOIN to retain left table rows (UNNEST columns are NULL when no match):
+```sql
+SELECT i.id, t.tag, i.name
+FROM items i
+LEFT JOIN unnest(i.tags) AS t(tag) ON t.tag = i.name;
+```
+Output (example):
+```sql
++------+--------+---------------------+
+| id   | tag    | name                |
++------+--------+---------------------+
+|    1 | Laptop | Laptop              |
+|    2 | NULL   | Mechanical Keyboard |
+|    3 | NULL   | Basketball          |
+|    4 | NULL   | Badminton Racket    |
+|    5 | Shirt  | Shirt               |
++------+--------+---------------------+
+```
+6. Multiple ARRAY parameters / Map / Bitmap:
+```sql
+SELECT * FROM unnest([1,2], ['a','b']) AS t(c1, c2) ORDER BY 1;
++------+------+
+| c1   | c2   |
++------+------+
+|    1 | a    |
+|    2 | b    |
++------+------+
+
+SELECT * FROM unnest(bitmap_or(to_bitmap(23), to_bitmap(24))) AS t(col) ORDER 
BY 1;
++------+
+| col  |
++------+
+|   23 |
+|   24 |
++------+
+
+SELECT * FROM unnest({1:2, 3:4}) AS t(k, v) ORDER BY 1;
++------+------+
+| k    | v    |
++------+------+
+|    1 |    2 |
+|    3 |    4 |
++------+------+
+```
+7. In the SELECT list
+```sql
+SELECT tags, category_ids, unnest(tags), unnest(category_ids) from items ORDER 
BY 1, 2;
++-------------------------------------------------+--------------+--------------+----------------------+
+| tags                                            | category_ids | 
unnest(tags) | unnest(category_ids) |
++-------------------------------------------------+--------------+--------------+----------------------+
+| ["Clothing", "Office", "Shirt"]                 | [4]          | Clothing    
 |                    4 |
+| ["Clothing", "Office", "Shirt"]                 | [4]          | Office      
 |                 NULL |
+| ["Clothing", "Office", "Shirt"]                 | [4]          | Shirt       
 |                 NULL |
+| ["Electronics", "Accessories"]                  | [1, 2]       | Electronics 
 |                    1 |
+| ["Electronics", "Accessories"]                  | [1, 2]       | Accessories 
 |                    2 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | Electronics 
 |                    1 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | Office      
 |                    2 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | High-End    
 |                    3 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | Laptop      
 |                 NULL |
+| ["Sports", "Equipment"]                         | [3]          | Sports      
 |                    3 |
+| ["Sports", "Equipment"]                         | [3]          | Equipment   
 |                 NULL |
+| ["Sports", "Outdoor"]                           | [1, 3]       | Sports      
 |                    1 |
+| ["Sports", "Outdoor"]                           | [1, 3]       | Outdoor     
 |                    3 |
++-------------------------------------------------+--------------+--------------+----------------------+
+```
diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-functions/table-functions/unnest.md
 
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-functions/table-functions/unnest.md
new file mode 100644
index 00000000000..1942ca7f84f
--- /dev/null
+++ 
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-functions/table-functions/unnest.md
@@ -0,0 +1,208 @@
+---
+{
+    "title": "UNNEST",
+    "language": "zh-CN"
+}
+---
+
+## 描述
+`unnest` 将数组/集合/映射类型表达式展开为多行(表生成函数)。支持在 SELECT 列表、FROM 中使用,并支持 WITH ORDINALITY 
为每个展开行附加序号。与 `explode` 系列函数类似,但 `unnest` 支持多参数、Map 与 Bitmap 等类型,并在 FROM/LATERAL 
与 JOIN 场景下支持 LEFT (outer) 语义。
+
+## 语法
+```sql
+UNNEST(<expr>[, ...]) [WITH ORDINALITY] [AS alias [(col1, col2, ...)]]
+-- 可在 FROM 子句前加 LATERAL: LATERAL UNNEST(...), LATERAL是个可选关键字
+```
+
+## 参数
+- <expr>:可为 ARRAY、MAP、BITMAP,或为表达式列表(多个参数时,只支持ARRAY类型)。
+
+## 返回值
+- 单个 ARRAY 参数:返回元素类型的单列多行(每个元素一行)。元素为 NULL 时输出 NULL。
+- 多个 ARRAY 参数:将每次展开的元素按位置组合为多列(或作为 Struct),展开长度由最长输入决定,短列用 NULL 补齐。
+- MAP 参数:返回 (key, value) 两列(Struct);NULL key/value 保持 NULL。
+- BITMAP 参数:按元素返回整型。
+- WITH ORDINALITY:在输出中附加一个从 1 开始的序号列(作为最后一列或由别名指定)。
+- 空数组或 NULL:
+  - 作为独立表生成(SELECT 列表或 FROM ... UNNEST)时,若参数为 NULL 或空数组,不产生行(0 行)。
+  - 在 FROM/LATERAL 与 LEFT JOIN 联合使用时(即产生 outer 
行语义),若某个父行的所有展开行被过滤或无输出,会为该父行插入一行,其中 UNNEST 输出列为 NULL(以保留左表行)。
+
+## 使用说明
+1. 参数类型必须是(ARRAY / MAP / BITMAP);否则报错。
+2. 多参数展开时,按位置配对;不足的列用 NULL 补齐。
+3. 可用 AS 别名并显式指定展开列名;若不指定列名,系统会生成默认列名。
+4. 在 JOIN 场景:
+   - INNER / CROSS JOIN:按展开结果做笛卡尔或匹配。
+   - LEFT JOIN LATERAL:实现 outer 行语义——若没有匹配或展开结果被 ON/过滤条件全部过滤,会产生一行 NULL(保持左表行)。
+5. WITH ORDINALITY 为展开行增加序号(1 起)。
+6. 在 SELECT 列表直接使用 `UNNEST(...)` 时,等价于对一个单行源应用表生成函数,会把该表达式展开为多行输出。
+
+## 示例
+准备:
+```sql
+CREATE TABLE items (
+    id INT,
+    name VARCHAR(50),
+    tags ARRAY<VARCHAR(50)>, 
+    price DECIMAL(10,2),
+    category_ids ARRAY<INT>  
+) ENGINE=OLAP
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 10
+PROPERTIES (
+    "replication_allocation" = "tag.location.default: 1"
+);
+
+INSERT INTO items (id, name, tags, price, category_ids) VALUES
+        (1, 'Laptop', ['Electronics', 'Office', 'High-End', 'Laptop'], 
5999.99, [1, 2, 3]),
+        (2, 'Mechanical Keyboard', ['Electronics', 'Accessories'], 399.99, [1, 
2]),
+        (3, 'Basketball', ['Sports', 'Outdoor'], 199.99, [1,3]),
+        (4, 'Badminton Racket', ['Sports', 'Equipment'], 299.99, [3]),
+        (5, 'Shirt', ['Clothing', 'Office', 'Shirt'], 259.00, [4]);
+```
+1. 作为 SELECT 列表(单表达式展开为多行):
+```sql
+SELECT unnest([1,2,3]);
+```
+输出(示例):
+```sql
++-----------------+
+| unnest([1,2,3]) |
++-----------------+
+|               1 |
+|               2 |
+|               3 |
++-----------------+
+```
+2. FROM / LATERAL 展开并指定列名:
+```sql
+SELECT i.id, t.tag
+FROM items i, unnest(i.tags) AS t(tag)
+ORDER BY i.id, t.tag;
+```
+输出(示例):
+```sql
++------+-------------+
+| id   | tag         |
++------+-------------+
+|    1 | Electronics |
+|    1 | High-End    |
+|    1 | Laptop      |
+|    1 | Office      |
+|    2 | Accessories |
+|    2 | Electronics |
+|    3 | Outdoor     |
+|    3 | Sports      |
+|    4 | Equipment   |
+|    4 | Sports      |
+|    5 | Clothing    |
+|    5 | Office      |
+|    5 | Shirt       |
++------+-------------+
+```
+3. WITH ORDINALITY:
+```sql
+SELECT i.id, t.ord, t.tag
+FROM items i, unnest(i.tags) WITH ORDINALITY AS t(tag, ord)
+ORDER BY i.id, t.ord;
+```
+输出(示例):
+```sql
++------+-------------+------+
+| id   | ord         | tag  |
++------+-------------+------+
+|    1 | Electronics |    0 |
+|    1 | High-End    |    2 |
+|    1 | Laptop      |    3 |
+|    1 | Office      |    1 |
+|    2 | Accessories |    1 |
+|    2 | Electronics |    0 |
+|    3 | Outdoor     |    1 |
+|    3 | Sports      |    0 |
+|    4 | Equipment   |    1 |
+|    4 | Sports      |    0 |
+|    5 | Clothing    |    0 |
+|    5 | Office      |    1 |
+|    5 | Shirt       |    2 |
++------+-------------+------+
+```
+4. INNER JOIN 保留匹配行:
+```sql
+SELECT i.id, t.tag, i.name
+FROM items i
+INNER JOIN unnest(i.tags) AS t(tag) ON t.tag = i.name;
+```
+输出(示例):
+```sql
++------+--------+--------+
+| id   | tag    | name   |
++------+--------+--------+
+|    1 | Laptop | Laptop |
+|    5 | Shirt  | Shirt  |
++------+--------+--------+
+```
+5. LEFT JOIN 保留左表行(无匹配时 UNNEST 列为 NULL):
+```sql
+SELECT i.id, t.tag, i.name
+FROM items i
+LEFT JOIN unnest(i.tags) AS t(tag) ON t.tag = i.name;
+```
+输出(示例):
+```sql
++------+--------+---------------------+
+| id   | tag    | name                |
++------+--------+---------------------+
+|    1 | Laptop | Laptop              |
+|    2 | NULL   | Mechanical Keyboard |
+|    3 | NULL   | Basketball          |
+|    4 | NULL   | Badminton Racket    |
+|    5 | Shirt  | Shirt               |
++------+--------+---------------------+
+```
+6. 多ARRAY参数 / Map / Bitmap:
+```sql
+SELECT * FROM unnest([1,2], ['a','b']) AS t(c1, c2) ORDER BY 1;
++------+------+
+| c1   | c2   |
++------+------+
+|    1 | a    |
+|    2 | b    |
++------+------+
+
+SELECT * FROM unnest(bitmap_or(to_bitmap(23), to_bitmap(24))) AS t(col) ORDER 
BY 1;
++------+
+| col  |
++------+
+|   23 |
+|   24 |
++------+
+
+SELECT * FROM unnest({1:2, 3:4}) AS t(k, v) ORDER BY 1;
++------+------+
+| k    | v    |
++------+------+
+|    1 |    2 |
+|    3 |    4 |
++------+------+
+```
+7. 在 SELECT 列表中
+```sql
+SELECT tags, category_ids, unnest(tags), unnest(category_ids) from items ORDER 
BY 1, 2;
++-------------------------------------------------+--------------+--------------+----------------------+
+| tags                                            | category_ids | 
unnest(tags) | unnest(category_ids) |
++-------------------------------------------------+--------------+--------------+----------------------+
+| ["Clothing", "Office", "Shirt"]                 | [4]          | Clothing    
 |                    4 |
+| ["Clothing", "Office", "Shirt"]                 | [4]          | Office      
 |                 NULL |
+| ["Clothing", "Office", "Shirt"]                 | [4]          | Shirt       
 |                 NULL |
+| ["Electronics", "Accessories"]                  | [1, 2]       | Electronics 
 |                    1 |
+| ["Electronics", "Accessories"]                  | [1, 2]       | Accessories 
 |                    2 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | Electronics 
 |                    1 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | Office      
 |                    2 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | High-End    
 |                    3 |
+| ["Electronics", "Office", "High-End", "Laptop"] | [1, 2, 3]    | Laptop      
 |                 NULL |
+| ["Sports", "Equipment"]                         | [3]          | Sports      
 |                    3 |
+| ["Sports", "Equipment"]                         | [3]          | Equipment   
 |                 NULL |
+| ["Sports", "Outdoor"]                           | [1, 3]       | Sports      
 |                    1 |
+| ["Sports", "Outdoor"]                           | [1, 3]       | Outdoor     
 |                    3 |
++-------------------------------------------------+--------------+--------------+----------------------+
+```


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to