Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
88807617
提交
88807617
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Parse remaining types of window frames
上级
a1314402
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
341 行增加
和
149 行删除
+341
-149
Parser.java
h2/src/main/org/h2/command/Parser.java
+63
-40
Window.java
h2/src/main/org/h2/expression/aggregate/Window.java
+5
-0
WindowFrame.java
h2/src/main/org/h2/expression/aggregate/WindowFrame.java
+78
-107
WindowFrameBound.java
...rc/main/org/h2/expression/aggregate/WindowFrameBound.java
+102
-0
WindowFrameExclusion.java
...ain/org/h2/expression/aggregate/WindowFrameExclusion.java
+51
-0
WindowFrameUnits.java
...rc/main/org/h2/expression/aggregate/WindowFrameUnits.java
+40
-0
nth_value.sql
...c/test/org/h2/test/scripts/functions/window/nth_value.sql
+2
-2
没有找到文件。
h2/src/main/org/h2/command/Parser.java
浏览文件 @
88807617
...
...
@@ -176,8 +176,10 @@ import org.h2.expression.aggregate.Aggregate.AggregateType;
import
org.h2.expression.aggregate.JavaAggregate
;
import
org.h2.expression.aggregate.Window
;
import
org.h2.expression.aggregate.WindowFrame
;
import
org.h2.expression.aggregate.WindowFrame.SimpleExtent
;
import
org.h2.expression.aggregate.WindowFrame.WindowFrameExclusion
;
import
org.h2.expression.aggregate.WindowFrameBound
;
import
org.h2.expression.aggregate.WindowFrameBound.WindowFrameBoundType
;
import
org.h2.expression.aggregate.WindowFrameExclusion
;
import
org.h2.expression.aggregate.WindowFrameUnits
;
import
org.h2.expression.aggregate.WindowFunction
;
import
org.h2.expression.aggregate.WindowFunction.WindowFunctionType
;
import
org.h2.index.Index
;
...
...
@@ -3074,8 +3076,7 @@ public class Parser {
frame
=
readWindowFrame
();
break
;
default
:
frame
=
new
WindowFrame
(
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
,
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
);
frame
=
null
;
}
}
else
{
frame
=
readWindowFrame
();
...
...
@@ -3092,46 +3093,68 @@ public class Parser {
}
private
WindowFrame
readWindowFrame
()
{
SimpleExtent
extent
;
WindowFrameUnits
units
;
if
(
readIf
(
"ROWS"
))
{
units
=
WindowFrameUnits
.
ROWS
;
}
else
if
(
readIf
(
"RANGE"
))
{
units
=
WindowFrameUnits
.
RANGE
;
}
else
if
(
readIf
(
"GROUPS"
))
{
units
=
WindowFrameUnits
.
GROUPS
;
}
else
{
return
null
;
}
WindowFrameBound
starting
,
following
;
if
(
readIf
(
"BETWEEN"
))
{
starting
=
readWindowFrameStarting
();
read
(
"AND"
);
following
=
readWindowFrameFollowing
();
}
else
{
starting
=
readWindowFrameStarting
();
following
=
null
;
}
WindowFrameExclusion
exclusion
=
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
;
if
(
readIf
(
"RANGE"
))
{
read
(
"BETWEEN"
);
if
(
readIf
(
"UNBOUNDED"
))
{
read
(
"PRECEDING"
);
read
(
"AND"
);
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
extent
=
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
;
}
else
{
read
(
"UNBOUNDED"
);
read
(
"FOLLOWING"
);
extent
=
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_UNBOUNDED_FOLLOWING
;
}
}
else
{
read
(
"CURRENT"
);
if
(
readIf
(
"EXCLUDE"
))
{
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
read
(
"AND"
);
read
(
"UNBOUNDED"
);
read
(
"FOLLOWING"
);
extent
=
SimpleExtent
.
RANGE_BETWEEN_CURRENT_ROW_AND_UNBOUNDED_FOLLOWING
;
}
if
(
readIf
(
"EXCLUDE"
))
{
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
exclusion
=
WindowFrameExclusion
.
EXCLUDE_CURRENT_ROW
;
}
else
if
(
readIf
(
GROUP
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_GROUP
;
}
else
if
(
readIf
(
"TIES"
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_TIES
;
}
else
{
read
(
"NO"
);
read
(
"OTHERS"
);
}
exclusion
=
WindowFrameExclusion
.
EXCLUDE_CURRENT_ROW
;
}
else
if
(
readIf
(
GROUP
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_GROUP
;
}
else
if
(
readIf
(
"TIES"
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_TIES
;
}
else
{
read
(
"NO"
);
read
(
"OTHERS"
);
}
}
else
{
extent
=
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
;
}
return
new
WindowFrame
(
extent
,
exclusion
);
return
new
WindowFrame
(
units
,
starting
,
following
,
exclusion
);
}
private
WindowFrameBound
readWindowFrameStarting
()
{
if
(
readIf
(
"UNBOUNDED"
))
{
read
(
"PRECEDING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED
,
0
);
}
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
CURRENT_ROW
,
0
);
}
int
value
=
readNonNegativeInt
();
read
(
"PRECEDING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
VALUE
,
value
);
}
private
WindowFrameBound
readWindowFrameFollowing
()
{
if
(
readIf
(
"UNBOUNDED"
))
{
read
(
"FOLLOWING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED
,
0
);
}
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
CURRENT_ROW
,
0
);
}
int
value
=
readNonNegativeInt
();
read
(
"FOLLOWING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
VALUE
,
value
);
}
private
AggregateType
getAggregateType
(
String
name
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/Window.java
浏览文件 @
88807617
...
...
@@ -10,6 +10,7 @@ import java.util.ArrayList;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.aggregate.WindowFrameBound.WindowFrameBoundType
;
import
org.h2.result.SortOrder
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
...
...
@@ -64,6 +65,10 @@ public final class Window {
public
Window
(
ArrayList
<
Expression
>
partitionBy
,
ArrayList
<
SelectOrderBy
>
orderBy
,
WindowFrame
frame
)
{
this
.
partitionBy
=
partitionBy
;
this
.
orderBy
=
orderBy
;
if
(
frame
==
null
)
{
frame
=
new
WindowFrame
(
WindowFrameUnits
.
RANGE
,
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED
,
0
),
null
,
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
);
}
this
.
frame
=
frame
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrame.java
浏览文件 @
88807617
...
...
@@ -11,6 +11,7 @@ import java.util.Collections;
import
java.util.Iterator
;
import
java.util.NoSuchElementException
;
import
org.h2.expression.aggregate.WindowFrameBound.WindowFrameBoundType
;
import
org.h2.message.DbException
;
import
org.h2.result.SortOrder
;
import
org.h2.value.Value
;
...
...
@@ -20,92 +21,6 @@ import org.h2.value.Value;
*/
public
final
class
WindowFrame
{
/**
* Simple extent.
*/
public
enum
SimpleExtent
{
/**
* RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW frame specification.
*/
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
(
"RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"
),
/**
* RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING frame specification.
*/
RANGE_BETWEEN_CURRENT_ROW_AND_UNBOUNDED_FOLLOWING
(
"RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING"
),
/**
* RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING frame
* specification.
*/
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_UNBOUNDED_FOLLOWING
(
"RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
),
;
private
final
String
sql
;
private
SimpleExtent
(
String
sql
)
{
this
.
sql
=
sql
;
}
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
sql
;
}
}
/**
* Window frame exclusion clause.
*/
public
enum
WindowFrameExclusion
{
/**
* EXCLUDE CURRENT ROW exclusion clause.
*/
EXCLUDE_CURRENT_ROW
(
"EXCLUDE CURRENT ROW"
),
/**
* EXCLUDE GROUP exclusion clause.
*/
EXCLUDE_GROUP
(
"EXCLUDE GROUP"
),
/**
* EXCLUDE TIES exclusion clause.
*/
EXCLUDE_TIES
(
"EXCLUDE TIES"
),
/**
* EXCLUDE NO OTHERS exclusion clause.
*/
EXCLUDE_NO_OTHERS
(
"EXCLUDE NO OTHERS"
),
;
private
final
String
sql
;
private
WindowFrameExclusion
(
String
sql
)
{
this
.
sql
=
sql
;
}
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
sql
;
}
}
private
abstract
class
Itr
implements
Iterator
<
Value
[]>
{
final
ArrayList
<
Value
[]>
orderedRows
;
...
...
@@ -231,20 +146,34 @@ public final class WindowFrame {
}
private
final
SimpleExtent
extent
;
private
final
WindowFrameUnits
units
;
private
final
WindowFrameBound
starting
;
private
final
WindowFrameBound
following
;
private
final
WindowFrameExclusion
exclusion
;
/**
* Creates new instance of window frame clause.
*
* @param extent
* window frame extent
* @param units
* units
* @param starting
* starting clause
* @param following
* following clause
* @param exclusion
*
window frame exclusion
*
exclusion clause
*/
public
WindowFrame
(
SimpleExtent
extent
,
WindowFrameExclusion
exclusion
)
{
this
.
extent
=
extent
;
public
WindowFrame
(
WindowFrameUnits
units
,
WindowFrameBound
starting
,
WindowFrameBound
following
,
WindowFrameExclusion
exclusion
)
{
this
.
units
=
units
;
this
.
starting
=
starting
;
if
(
following
!=
null
&&
following
.
getType
()
==
WindowFrameBoundType
.
CURRENT_ROW
)
{
following
=
null
;
}
this
.
following
=
following
;
this
.
exclusion
=
exclusion
;
}
...
...
@@ -254,7 +183,7 @@ public final class WindowFrame {
* @return whether window frame specification can be omitted
*/
public
boolean
isDefault
()
{
return
extent
==
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
return
starting
.
getType
()
==
WindowFrameBoundType
.
UNBOUNDED
&&
following
==
null
&&
exclusion
==
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
;
}
...
...
@@ -265,7 +194,8 @@ public final class WindowFrame {
* @return whether window frame specification contains all rows in partition
*/
public
boolean
isFullPartition
()
{
return
extent
==
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_UNBOUNDED_FOLLOWING
return
starting
.
getType
()
==
WindowFrameBoundType
.
UNBOUNDED
&&
following
!=
null
&&
following
.
getType
()
==
WindowFrameBoundType
.
UNBOUNDED
&&
exclusion
==
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
;
}
...
...
@@ -285,22 +215,57 @@ public final class WindowFrame {
public
Iterator
<
Value
[]>
iterator
(
ArrayList
<
Value
[]>
orderedRows
,
SortOrder
sortOrder
,
int
currentRow
,
boolean
reverse
)
{
int
size
=
orderedRows
.
size
();
final
int
startIndex
,
endIndex
;
switch
(
extent
)
{
case
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
:
final
int
startIndex
;
switch
(
starting
.
getType
()
)
{
case
UNBOUNDED
:
startIndex
=
0
;
endIndex
=
currentRow
;
break
;
case
RANGE_BETWEEN_CURRENT_ROW_AND_UNBOUNDED_FOLLOWING
:
case
CURRENT_ROW
:
startIndex
=
currentRow
;
endIndex
=
size
-
1
;
break
;
case
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_UNBOUNDED_FOLLOWING:
startIndex
=
0
;
endIndex
=
size
-
1
;
case
VALUE:
switch
(
units
)
{
case
ROWS:
{
int
value
=
starting
.
getValue
();
startIndex
=
value
>
currentRow
?
0
:
currentRow
-
value
;
break
;
}
default
:
// TODO
throw
DbException
.
getUnsupportedException
(
"units="
+
units
);
}
break
;
default
:
throw
DbException
.
getUnsupportedException
(
"window frame extent ="
+
extent
);
throw
DbException
.
getUnsupportedException
(
"window frame bound type="
+
starting
.
getType
());
}
int
endIndex
;
if
(
following
==
null
)
{
endIndex
=
currentRow
;
}
else
{
switch
(
following
.
getType
())
{
case
UNBOUNDED:
endIndex
=
size
-
1
;
break
;
case
CURRENT_ROW:
endIndex
=
currentRow
;
break
;
case
VALUE:
switch
(
units
)
{
case
ROWS:
{
int
value
=
following
.
getValue
();
int
rem
=
size
-
currentRow
-
1
;
endIndex
=
value
>
rem
?
size
-
1
:
currentRow
+
value
;
break
;
}
default
:
// TODO
throw
DbException
.
getUnsupportedException
(
"units="
+
units
);
}
break
;
default
:
throw
DbException
.
getUnsupportedException
(
"window frame bound type="
+
following
.
getType
());
}
}
if
(
exclusion
!=
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
)
{
return
complexIterator
(
orderedRows
,
sortOrder
,
currentRow
,
startIndex
,
endIndex
,
reverse
);
...
...
@@ -350,11 +315,17 @@ public final class WindowFrame {
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
String
sql
=
extent
.
getSQL
();
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
units
.
getSQL
());
if
(
following
==
null
)
{
builder
.
append
(
' '
).
append
(
starting
.
getSQL
(
false
));
}
else
{
builder
.
append
(
" BETWEEN "
).
append
(
starting
.
getSQL
(
false
)).
append
(
" AND "
).
append
(
following
.
getSQL
(
true
));
}
if
(
exclusion
!=
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
)
{
sql
=
sql
+
' '
+
exclusion
.
getSQL
(
);
builder
.
append
(
' '
).
append
(
exclusion
.
getSQL
()
);
}
return
sql
;
return
builder
.
toString
()
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrameBound.java
0 → 100644
浏览文件 @
88807617
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
/**
* Window frame bound.
*/
public
class
WindowFrameBound
{
/**
* Window frame bound type.
*/
public
enum
WindowFrameBoundType
{
/**
* UNBOUNDED PRECEDING or UNBOUNDED FOLLOWING clause.
*/
UNBOUNDED
,
/**
* CURRENT_ROW clause.
*/
CURRENT_ROW
,
/**
* PRECEDING or FOLLOWING clause.
*/
VALUE
;
}
private
final
WindowFrameBoundType
type
;
private
final
int
value
;
/**
* Creates new instance of window frame bound.
*
* @param type
* bound type
* @param value
* bound value, if any
*/
public
WindowFrameBound
(
WindowFrameBoundType
type
,
int
value
)
{
this
.
type
=
type
;
if
(
type
==
WindowFrameBoundType
.
VALUE
)
{
if
(
value
<
0
)
{
throw
DbException
.
getInvalidValueException
(
"unsigned"
,
value
);
}
this
.
value
=
value
;
}
else
{
this
.
value
=
0
;
}
}
/**
* Returns the type
*
* @return the type
*/
public
WindowFrameBoundType
getType
()
{
return
type
;
}
/**
* Returns the value.
*
* @return the value
*/
public
int
getValue
()
{
return
value
;
}
/**
* Returns SQL representation.
*
* @param following
* if false return SQL for starting clause, if true return SQL
* for following clause
* @return SQL representation.
* @see Expression#getSQL()
*/
public
String
getSQL
(
boolean
following
)
{
switch
(
type
)
{
case
UNBOUNDED:
return
following
?
"UNBOUNDED FOLLOWING"
:
"UNBOUNDED PRECEDING"
;
case
CURRENT_ROW:
return
"CURRENT ROW"
;
case
VALUE:
return
value
+
(
following
?
" FOLLOWING"
:
" PRECEDING"
);
default
:
throw
DbException
.
throwInternalError
(
"type="
+
type
);
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrameExclusion.java
0 → 100644
浏览文件 @
88807617
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
.
aggregate
;
/**
* Window frame exclusion clause.
*/
public
enum
WindowFrameExclusion
{
/**
* EXCLUDE CURRENT ROW exclusion clause.
*/
EXCLUDE_CURRENT_ROW
(
"EXCLUDE CURRENT ROW"
),
/**
* EXCLUDE GROUP exclusion clause.
*/
EXCLUDE_GROUP
(
"EXCLUDE GROUP"
),
/**
* EXCLUDE TIES exclusion clause.
*/
EXCLUDE_TIES
(
"EXCLUDE TIES"
),
/**
* EXCLUDE NO OTHERS exclusion clause.
*/
EXCLUDE_NO_OTHERS
(
"EXCLUDE NO OTHERS"
),
;
private
final
String
sql
;
private
WindowFrameExclusion
(
String
sql
)
{
this
.
sql
=
sql
;
}
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
sql
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrameUnits.java
0 → 100644
浏览文件 @
88807617
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
.
aggregate
;
/**
* Window frame units.
*/
public
enum
WindowFrameUnits
{
/**
* ROWS unit.
*/
ROWS
,
/**
* RANGE unit.
*/
RANGE
,
/**
* GROUPS unit.
*/
GROUPS
,
;
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
name
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/window/nth_value.sql
浏览文件 @
88807617
...
...
@@ -139,8 +139,8 @@ SELECT ID, CATEGORY,
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
CURRENT
ROW
)
C
,
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
CURRENT
ROW
EXCLUDE
CURRENT
ROW
)
FROM
TEST
FETCH
FIRST
3
ROWS
ONLY
;
>
ID
CATEGORY
C
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
CURRENT
ROW
EXCLUDE
CURRENT
ROW
)
>
-- -------- ---- ---------------------------------------------------------------------------------------------
------------------------
>
ID
CATEGORY
C
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
UNBOUNDED
PRECEDING
EXCLUDE
CURRENT
ROW
)
>
-- -------- ---- ---------------------------------------------------------------------------------------------
>
1
1
null
null
>
2
1
1
null
>
3
1
1
1
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论