WINDOW FUNCTION 
====================================

WINDOW FUNCTION 算子用于实现 SQL 中的分析函数（也叫窗口函数），计算窗口下的相关行的结果。

窗口函数与聚集函数不同的是，聚集函数一组只能返回一行，而窗口函数每组可以返回多行，组内每一行都是基于窗口的逻辑计算的结果。因此，在执行含有 WINDOW FUNCTION 的 SQL 时 (格式一般为 `OVER(...)`），都会在生成执行计划的时候分配一个 WINDOW FUNCTION 算子。

示例：含 WINDOW FUNCTION 算子的执行计划

```javascript
obclient>CREATE TABLE t1(c1 INT, c2 INT);
Query OK, 0 rows affected (0.12 sec)

obclient>INSERT INTO t1 VALUES(1, 1);
Query OK, 1 rows affected (0.12 sec)

obclient>INSERT INTO t1 VALUES(2, 2);
Query OK, 1 rows affected (0.12 sec)

obclient>INSERT INTO t1 VALUES(3, 3);
Query OK, 1 rows affected (0.12 sec)

Q1: 
obclient>EXPLAIN SELECT MAX(c1) OVER(PARTITION BY c1 ORDER BY c2) FROM t1\G;
*************************** 1. row ***************************
Query Plan:
| ========================================
|ID|OPERATOR       |NAME|EST. ROWS|COST|
----------------------------------------
|0 |WINDOW FUNCTION|    |3        |45  |
|1 | SORT          |    |3        |44  |
|2 |  TABLE SCAN   |T1  |3        |37  |
========================================

Outputs & filters: 
-------------------------------------
  0 - output([T_FUN_MAX(T1.C1)]), filter(nil), 
      win_expr(T_FUN_MAX(T1.C1)), partition_by([T1.C1]), order_by([T1.C2, ASC]), window_type(RANGE), upper(UNBOUNDED PRECEDING), lower(CURRENT ROW)
  1 - output([T1.C1], [T1.C2]), filter(nil), sort_keys([T1.C1, ASC], [T1.C2, ASC])
  2 - output([T1.C1], [T1.C2]), filter(nil), 
      access([T1.C1], [T1.C2]), partitions(p0)
```



其中，窗口函数中指定了一个 ORDER BY/PARTITION BY 的时候，会在下层分配一个 SORT 算子，将排序结果返回给窗口函数算子使用。

上述示例中，Q1 查询的执行计划展示中的 outputs \& filters 详细列出了 WINDOW FUNCTION 算子的输出信息如下：


|   **信息名称**   |                                                                                                                                                        **含义**                                                                                                                                                         |
|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| output       | 该算子输出的表达式。                                                                                                                                                                                                                                                                                                            |
| filter       | 该算子上的过滤条件。 由于示例中 WINDOW FUNCTION 算子没有设置 filter，所以为 nil。                                                                                                                                                                                                                                               |
| win_expr     | 在窗口中使用何种聚合函数。 例如，Q1 查询为求 c1 列的最大值，因此为`T_FUN_MAX(t1.c1)`。                                                                                                                                                                                                                                              |
| partition_by | 在窗口中按照何种方式分组。 例如，Q1 查询为按照 c1 列分组，因此为 `t1.c1`。                                                                                                                                                                                                                                                         |
| order_by     | 在窗口中按照何种方式排序。 例如，Q1 查询为按照 c2 列排序，因此为 `t1.c2`。                                                                                                                                                                                                                                                         |
| window_type  | 窗口类型，包括 range 和 rows 两种： * range ：按照逻辑位置偏移进行计算窗口上下界限，默认使用 range 方式。   * rows ：按照实际物理位置偏移进行计算窗口上下界限。    例如，Q1 查询未设置窗口类型，因此选择了默认方式 range。                                                                            |
| upper        | 设定窗口的上边界： * UNBOUNDED ：无边界，选择最大的值（默认）。   * CURRENT ROW ：从当前行开始，如果出现数字则表示移动的行数。   * PRECEDING ：向前取边   * FOLLOWING：向后取边界。    例如，Q1 查询设置的上边界为向前无边界。 |
| lower        | 设定窗口的下边界，边界属性设置同 upper。 例如，Q1 查询设置的下边界为当前行。                                                                                                                                                                                                                                                           |



