Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
8863b2db
提交
8863b2db
authored
9月 20, 2018
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add WINDOW clause support
上级
3b4620a2
显示空白字符变更
内嵌
并排
正在显示
23 个修改的文件
包含
222 行增加
和
60 行删除
+222
-60
help.csv
h2/src/docsrc/help/help.csv
+48
-35
advanced.html
h2/src/docsrc/html/advanced.html
+1
-1
_messages_en.prop
h2/src/docsrc/textbase/_messages_en.prop
+1
-1
ErrorCode.java
h2/src/main/org/h2/api/ErrorCode.java
+11
-1
Parser.java
h2/src/main/org/h2/command/Parser.java
+32
-2
Select.java
h2/src/main/org/h2/command/dml/Select.java
+28
-0
Window.java
h2/src/main/org/h2/expression/aggregate/Window.java
+33
-4
JdbcDatabaseMetaData.java
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
+1
-1
DbException.java
h2/src/main/org/h2/message/DbException.java
+1
-0
_messages_cs.prop
h2/src/main/org/h2/res/_messages_cs.prop
+1
-1
_messages_de.prop
h2/src/main/org/h2/res/_messages_de.prop
+1
-1
_messages_en.prop
h2/src/main/org/h2/res/_messages_en.prop
+1
-1
_messages_es.prop
h2/src/main/org/h2/res/_messages_es.prop
+1
-1
_messages_fr.prop
h2/src/main/org/h2/res/_messages_fr.prop
+1
-1
_messages_ja.prop
h2/src/main/org/h2/res/_messages_ja.prop
+1
-1
_messages_pl.prop
h2/src/main/org/h2/res/_messages_pl.prop
+1
-1
_messages_pt_br.prop
h2/src/main/org/h2/res/_messages_pt_br.prop
+1
-1
_messages_ru.prop
h2/src/main/org/h2/res/_messages_ru.prop
+1
-1
_messages_sk.prop
h2/src/main/org/h2/res/_messages_sk.prop
+1
-1
_messages_zh_cn.prop
h2/src/main/org/h2/res/_messages_zh_cn.prop
+1
-1
ParserUtil.java
h2/src/main/org/h2/util/ParserUtil.java
+11
-4
TestScript.java
h2/src/test/org/h2/test/scripts/TestScript.java
+1
-0
window.sql
h2/src/test/org/h2/test/scripts/window.sql
+43
-0
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
8863b2db
...
...
@@ -8,6 +8,7 @@ SELECT [ TOP term [ PERCENT ] [ WITH TIES ] ]
selectExpression [,...]
FROM tableExpression [,...] [ WHERE expression ]
[ GROUP BY expression [,...] ] [ HAVING expression ]
[ WINDOW { { windowName AS windowSpecification } [,...] } ]
[ { UNION [ ALL ] | MINUS | EXCEPT | INTERSECT } select ]
[ ORDER BY order [,...] ]
[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ]
...
...
@@ -2533,17 +2534,27 @@ The column list of the resulting table is C1, C2, and so on.
SELECT * FROM (VALUES(1, 'Hello'), (2, 'World')) AS V;
"
"Other Grammar","Window specification","
([PARTITION BY expression [,...]] [ORDER BY order [,...]]
[windowFrame])
"Other Grammar","Window name or specification","
windowName | windowSpecification
","
A window specification for a window function or aggregate.
A window
name or inline
specification for a window function or aggregate.
Window functions are currently experimental in H2 and should be used with caution.
They also may require a lot of memory for large queries.
","
()
W1
(ORDER BY ID)
"
"Other Grammar","Window specification","
([existingWindowName]
[PARTITION BY expression [,...]] [ORDER BY order [,...]]
[windowFrame])
","
A window specification for a window, window function or aggregate.
","
()
(W1 ORDER BY ID)
(PARTITION BY CATEGORY)
(PARTITION BY CATEGORY ORDER BY NAME, ID)
(ORDER BY Y RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE TIES)
...
...
@@ -3303,7 +3314,7 @@ INTERVAL MINUTE TO SECOND
"Functions (Aggregate)","AVG","
AVG ( [ DISTINCT ] { numeric } )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The average (mean) value.
If no rows are selected, the result is NULL.
...
...
@@ -3315,7 +3326,7 @@ AVG(X)
"Functions (Aggregate)","BIT_AND","
BIT_AND(expression)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The bitwise AND of all non-null values.
If no rows are selected, the result is NULL.
...
...
@@ -3326,7 +3337,7 @@ BIT_AND(ID)
"Functions (Aggregate)","BIT_OR","
BIT_OR(expression)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The bitwise OR of all non-null values.
If no rows are selected, the result is NULL.
...
...
@@ -3337,7 +3348,7 @@ BIT_OR(ID)
"Functions (Aggregate)","BOOL_AND","
BOOL_AND(boolean)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Returns true if all expressions are true.
If no rows are selected, the result is NULL.
...
...
@@ -3348,7 +3359,7 @@ BOOL_AND(ID>10)
"Functions (Aggregate)","BOOL_OR","
BOOL_OR(boolean)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Returns true if any expression is true.
If no rows are selected, the result is NULL.
...
...
@@ -3359,7 +3370,7 @@ BOOL_OR(NAME LIKE 'W%')
"Functions (Aggregate)","COUNT","
COUNT( { * | { [ DISTINCT ] expression } } )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The count of all row, or of the non-null values.
This method returns a long.
...
...
@@ -3373,7 +3384,7 @@ COUNT(*)
GROUP_CONCAT ( [ DISTINCT ] string
[ ORDER BY { expression [ ASC | DESC ] } [,...] ]
[ SEPARATOR expression ] )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Concatenates strings with a separator.
The default separator is a ',' (without space).
...
...
@@ -3387,7 +3398,7 @@ GROUP_CONCAT(NAME ORDER BY ID SEPARATOR ', ')
"Functions (Aggregate)","ARRAY_AGG","
ARRAY_AGG ( [ DISTINCT ] string
[ ORDER BY { expression [ ASC | DESC ] } [,...] ] )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Aggregate the value into an array.
This method returns an array.
...
...
@@ -3399,7 +3410,7 @@ ARRAY_AGG(NAME ORDER BY ID)
"Functions (Aggregate)","MAX","
MAX(value)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The highest value.
If no rows are selected, the result is NULL.
...
...
@@ -3411,7 +3422,7 @@ MAX(NAME)
"Functions (Aggregate)","MIN","
MIN(value)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The lowest value.
If no rows are selected, the result is NULL.
...
...
@@ -3423,7 +3434,7 @@ MIN(NAME)
"Functions (Aggregate)","SUM","
SUM( [ DISTINCT ] { numeric } )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The sum of all values.
If no rows are selected, the result is NULL.
...
...
@@ -3436,7 +3447,7 @@ SUM(X)
"Functions (Aggregate)","SELECTIVITY","
SELECTIVITY(value)
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Estimates the selectivity (0-100) of a value.
The value is defined as (100 * distinctCount / rowCount).
...
...
@@ -3449,7 +3460,7 @@ SELECT SELECTIVITY(FIRSTNAME), SELECTIVITY(NAME) FROM TEST WHERE ROWNUM()<20000
"Functions (Aggregate)","STDDEV_POP","
STDDEV_POP( [ DISTINCT ] numeric )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The population standard deviation.
This method returns a double.
...
...
@@ -3461,7 +3472,7 @@ STDDEV_POP(X)
"Functions (Aggregate)","STDDEV_SAMP","
STDDEV_SAMP( [ DISTINCT ] numeric )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The sample standard deviation.
This method returns a double.
...
...
@@ -3473,7 +3484,7 @@ STDDEV(X)
"Functions (Aggregate)","VAR_POP","
VAR_POP( [ DISTINCT ] numeric )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The population variance (square of the population standard deviation).
This method returns a double.
...
...
@@ -3485,7 +3496,7 @@ VAR_POP(X)
"Functions (Aggregate)","VAR_SAMP","
VAR_SAMP( [ DISTINCT ] numeric )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The sample variance (square of the sample standard deviation).
This method returns a double.
...
...
@@ -3497,7 +3508,7 @@ VAR_SAMP(X)
"Functions (Aggregate)","MEDIAN","
MEDIAN( [ DISTINCT ] value )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
The value separating the higher half of a values from the lower half.
Returns the middle value or an interpolated value between two middle values if number of values is even.
...
...
@@ -3512,7 +3523,7 @@ MEDIAN(X)
"Functions (Aggregate)","MODE","
{ MODE( value ) [ ORDER BY expression [ ASC | DESC ] ] }
| { MODE() WITHIN GROUP(ORDER BY expression [ ASC | DESC ]) }
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Returns the value that occurs with the greatest frequency.
If there are multiple values with the same frequency only one value will be returned.
...
...
@@ -3532,7 +3543,7 @@ MODE() WITHIN GROUP(ORDER BY X)
"Functions (Aggregate)","ENVELOPE","
ENVELOPE( value )
[FILTER (WHERE expression)] [OVER windowSpecification]
[FILTER (WHERE expression)] [OVER window
NameOr
Specification]
","
Returns the minimum bounding box that encloses all specified GEOMETRY values.
Only 2D coordinate plane is supported.
...
...
@@ -5105,7 +5116,7 @@ H2VERSION()
"
"Functions (Window)","ROW_NUMBER","
ROW_NUMBER() OVER windowSpecification
ROW_NUMBER() OVER window
NameOr
Specification
","
Returns the number of the current row starting with 1.
...
...
@@ -5118,7 +5129,7 @@ SELECT ROW_NUMBER() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
"
"Functions (Window)","RANK","
RANK() OVER windowSpecification
RANK() OVER window
NameOr
Specification
","
Returns the rank of the current row.
The rank of a row is the number of rows that precede this row plus 1.
...
...
@@ -5133,7 +5144,7 @@ SELECT RANK() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
"
"Functions (Window)","DENSE_RANK","
DENSE_RANK() OVER windowSpecification
DENSE_RANK() OVER window
NameOr
Specification
","
Returns the dense rank of the current row.
The rank of a row is the number of groups of rows with the same values in ORDER BY columns that precede group with this row plus 1.
...
...
@@ -5148,7 +5159,7 @@ SELECT DENSE_RANK() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
"
"Functions (Window)","PERCENT_RANK","
PERCENT_RANK() OVER windowSpecification
PERCENT_RANK() OVER window
NameOr
Specification
","
Returns the relative rank of the current row.
The relative rank is calculated as (RANK - 1) / (NR - 1),
...
...
@@ -5162,7 +5173,7 @@ SELECT PERCENT_RANK() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
"
"Functions (Window)","CUME_DIST","
CUME_DIST() OVER windowSpecification
CUME_DIST() OVER window
NameOr
Specification
","
Returns the relative rank of the current row.
The relative rank is calculated as NP / NR
...
...
@@ -5177,7 +5188,7 @@ SELECT CUME_DIST() OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
"
"Functions (Window)","NTILE","
NTILE(int) OVER windowSpecification
NTILE(int) OVER window
NameOr
Specification
","
Distributes the rows into a specified number of groups.
Number of groups should be a positive integer value.
...
...
@@ -5194,7 +5205,7 @@ SELECT NTILE(5) OVER (PARTITION BY CATEGORY ORDER BY ID), * FROM TEST;
"Functions (Window)","LEAD","
LEAD(value [, offsetInt [, defaultValue]]) [{RESPECT|IGNORE} NULLS]
OVER windowSpecification
OVER window
NameOr
Specification
","
Returns the value in a next row with specified offset relative to the current row.
Offset must be non-negative.
...
...
@@ -5214,7 +5225,7 @@ SELECT LEAD(X, 2, 0) IGNORE NULLS OVER (
"Functions (Window)","LAG","
LAG(value [, offsetInt [, defaultValue]]) [{RESPECT|IGNORE} NULLS]
OVER windowSpecification
OVER window
NameOr
Specification
","
Returns the value in a previous row with specified offset relative to the current row.
Offset must be non-negative.
...
...
@@ -5233,7 +5244,8 @@ SELECT LAG(X, 2, 0) IGNORE NULLS OVER (
"
"Functions (Window)","FIRST_VALUE","
FIRST_VALUE(value) [{RESPECT|IGNORE} NULLS] OVER windowSpecification
FIRST_VALUE(value) [{RESPECT|IGNORE} NULLS]
OVER windowNameOrSpecification
","
Returns the first value in a window.
If IGNORE NULLS is specified null values are skipped and the function returns first non-null value, if any.
...
...
@@ -5246,7 +5258,8 @@ SELECT FIRST_VALUE(X) IGNORE NULLS OVER (PARTITION BY CATEGORY ORDER BY ID), * F
"
"Functions (Window)","LAST_VALUE","
LAST_VALUE(value) [{RESPECT|IGNORE} NULLS] OVER windowSpecification
LAST_VALUE(value) [{RESPECT|IGNORE} NULLS]
OVER windowNameOrSpecification
","
Returns the last value in a window.
If IGNORE NULLS is specified null values are skipped and the function returns last non-null value before them, if any;
...
...
@@ -5265,7 +5278,7 @@ SELECT LAST_VALUE(X) IGNORE NULLS OVER (
"Functions (Window)","NTH_VALUE","
NTH_VALUE(value, nInt) [FROM {FIRST|LAST}] [{RESPECT|IGNORE} NULLS]
OVER windowSpecification
OVER window
NameOr
Specification
","
Returns the value in a row with a specified relative number in a window.
Relative row number must be positive.
...
...
h2/src/docsrc/html/advanced.html
浏览文件 @
8863b2db
...
...
@@ -488,7 +488,7 @@ ALL, CHECK, CONSTRAINT, CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DI
EXISTS, FALSE, FETCH, FOR, FOREIGN, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, INTERSECTS,
IS, JOIN, LIKE, LIMIT, LOCALTIME, LOCALTIMESTAMP, MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER,
PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, WHERE,
WITH
WI
NDOW, WI
TH
</code>
</p><p>
Certain words of this list are keywords because they are functions that can be used without '()' for compatibility,
...
...
h2/src/docsrc/textbase/_messages_en.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Cannot change the setting {0} when the database is already open
90134=Access to the class {0} is denied
90135=The database is open in exclusive mode; can not open additional connections
90136=
Unsupported outer join condition
: {0}
90136=
Window not found
: {0}
90137=Can only assign to a variable, not to: {0}
90138=Invalid database name: {0}
90139=The public static Java method was not found: {0}
...
...
h2/src/main/org/h2/api/ErrorCode.java
浏览文件 @
8863b2db
...
...
@@ -1926,6 +1926,16 @@ public class ErrorCode {
*/
public
static
final
int
DATABASE_IS_IN_EXCLUSIVE_MODE
=
90135
;
/**
* The error with code <code>90136</code> is thrown when
* trying to reference a window that does not exist.
* Example:
* <pre>
* SELECT LEAD(X) OVER W FROM TEST;
* </pre>
*/
public
static
final
int
WINDOW_NOT_FOUND_1
=
90136
;
/**
* The error with code <code>90137</code> is thrown when
* trying to assign a value to something that is not a variable.
...
...
@@ -2009,7 +2019,7 @@ public class ErrorCode {
public
static
final
int
AUTHENTICATOR_NOT_AVAILABLE
=
90144
;
// next
are 90136,
90145
// next
is
90145
private
ErrorCode
()
{
// utility class
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
8863b2db
...
...
@@ -44,6 +44,7 @@ import static org.h2.util.ParserUtil.TRUE;
import
static
org
.
h2
.
util
.
ParserUtil
.
UNION
;
import
static
org
.
h2
.
util
.
ParserUtil
.
UNIQUE
;
import
static
org
.
h2
.
util
.
ParserUtil
.
WHERE
;
import
static
org
.
h2
.
util
.
ParserUtil
.
WINDOW
;
import
static
org
.
h2
.
util
.
ParserUtil
.
WITH
;
import
java.math.BigDecimal
;
...
...
@@ -482,6 +483,8 @@ public class Parser {
"UNIQUE"
,
// WHERE
"WHERE"
,
// WINDOW
"WINDOW"
,
// WITH
"WITH"
,
// PARAMETER
...
...
@@ -2628,6 +2631,17 @@ public class Parser {
Expression
condition
=
readExpression
();
command
.
setHaving
(
condition
);
}
if
(
readIf
(
WINDOW
))
{
do
{
int
index
=
parseIndex
;
String
name
=
readAliasIdentifier
();
read
(
"AS"
);
Window
w
=
readWindowSpecification
();
if
(!
currentSelect
.
addWindow
(
name
,
w
))
{
throw
DbException
.
getSyntaxError
(
sqlCommand
,
index
,
"unique identifier"
);
}
}
while
(
readIf
(
COMMA
));
}
command
.
setParameterList
(
parameters
);
currentSelect
=
oldSelect
;
setSQL
(
command
,
"SELECT"
,
start
);
...
...
@@ -3049,7 +3063,7 @@ public class Parser {
}
Window
over
=
null
;
if
(
readIf
(
"OVER"
))
{
over
=
readWindowSpecification
();
over
=
readWindow
NameOr
Specification
();
aggregate
.
setOverCondition
(
over
);
currentSelect
.
setWindowQuery
();
}
else
if
(!
isAggregate
)
{
...
...
@@ -3059,8 +3073,24 @@ public class Parser {
}
}
private
Window
readWindowNameOrSpecification
()
{
return
isToken
(
OPEN_PAREN
)
?
readWindowSpecification
()
:
new
Window
(
readAliasIdentifier
(),
null
,
null
,
null
);
}
private
Window
readWindowSpecification
()
{
read
(
OPEN_PAREN
);
String
parent
=
null
;
if
(
currentTokenType
==
IDENTIFIER
)
{
String
token
=
currentToken
;
if
(
currentTokenQuoted
||
(
//
!
equalsToken
(
token
,
"PARTITION"
)
//
&&
!
equalsToken
(
token
,
"ROWS"
)
//
&&
!
equalsToken
(
token
,
"RANGE"
)
//
&&
!
equalsToken
(
token
,
"GROUPS"
)))
{
parent
=
token
;
read
();
}
}
ArrayList
<
Expression
>
partitionBy
=
null
;
if
(
readIf
(
"PARTITION"
))
{
read
(
"BY"
);
...
...
@@ -3077,7 +3107,7 @@ public class Parser {
}
WindowFrame
frame
=
readWindowFrame
();
read
(
CLOSE_PAREN
);
return
new
Window
(
partitionBy
,
orderBy
,
frame
);
return
new
Window
(
par
ent
,
par
titionBy
,
orderBy
,
frame
);
}
private
WindowFrame
readWindowFrame
()
{
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
8863b2db
...
...
@@ -8,6 +8,7 @@ package org.h2.command.dml;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.Trigger
;
...
...
@@ -25,6 +26,7 @@ import org.h2.expression.ExpressionVisitor;
import
org.h2.expression.Parameter
;
import
org.h2.expression.Wildcard
;
import
org.h2.expression.aggregate.Aggregate
;
import
org.h2.expression.aggregate.Window
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
import
org.h2.index.IndexType
;
...
...
@@ -116,6 +118,8 @@ public class Select extends Query {
private
boolean
isGroupWindowStage2
;
private
HashMap
<
String
,
Window
>
windows
;
public
Select
(
Session
session
)
{
super
(
session
);
}
...
...
@@ -214,6 +218,30 @@ public class Select extends Query {
return
distinct
||
distinctExpressions
!=
null
;
}
/**
* Adds a named window definition.
*
* @param name name
* @param window window definition
* @return true if a new definition was added, false if old definition was replaced
*/
public
boolean
addWindow
(
String
name
,
Window
window
)
{
if
(
windows
==
null
)
{
windows
=
new
HashMap
<>();
}
return
windows
.
put
(
name
,
window
)
==
null
;
}
/**
* Returns a window with specified name, or null.
*
* @param name name of the window
* @return the window with specified name, or null
*/
public
Window
getWindow
(
String
name
)
{
return
windows
!=
null
?
windows
.
get
(
name
)
:
null
;
}
/**
* Add a condition to the list of conditions.
*
...
...
h2/src/main/org/h2/expression/aggregate/Window.java
浏览文件 @
8863b2db
...
...
@@ -7,9 +7,11 @@ package org.h2.expression.aggregate;
import
java.util.ArrayList
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.result.SortOrder
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
...
...
@@ -22,11 +24,13 @@ import org.h2.value.ValueArray;
*/
public
final
class
Window
{
private
final
ArrayList
<
Expression
>
partitionBy
;
private
ArrayList
<
Expression
>
partitionBy
;
private
final
ArrayList
<
SelectOrderBy
>
orderBy
;
private
ArrayList
<
SelectOrderBy
>
orderBy
;
private
final
WindowFrame
frame
;
private
WindowFrame
frame
;
private
String
parent
;
/**
* @param builder
...
...
@@ -54,6 +58,8 @@ public final class Window {
/**
* Creates a new instance of window clause.
*
* @param parent
* name of the parent window
* @param partitionBy
* PARTITION BY clause, or null
* @param orderBy
...
...
@@ -61,7 +67,9 @@ public final class Window {
* @param frame
* window frame clause
*/
public
Window
(
ArrayList
<
Expression
>
partitionBy
,
ArrayList
<
SelectOrderBy
>
orderBy
,
WindowFrame
frame
)
{
public
Window
(
String
parent
,
ArrayList
<
Expression
>
partitionBy
,
ArrayList
<
SelectOrderBy
>
orderBy
,
WindowFrame
frame
)
{
this
.
parent
=
parent
;
this
.
partitionBy
=
partitionBy
;
this
.
orderBy
=
orderBy
;
this
.
frame
=
frame
;
...
...
@@ -77,6 +85,7 @@ public final class Window {
* @see Expression#mapColumns(ColumnResolver, int)
*/
public
void
mapColumns
(
ColumnResolver
resolver
,
int
level
)
{
resolveWindows
(
resolver
);
if
(
partitionBy
!=
null
)
{
for
(
Expression
e
:
partitionBy
)
{
e
.
mapColumns
(
resolver
,
level
);
...
...
@@ -89,6 +98,26 @@ public final class Window {
}
}
private
void
resolveWindows
(
ColumnResolver
resolver
)
{
if
(
parent
!=
null
)
{
Window
p
=
resolver
.
getSelect
().
getWindow
(
parent
);
if
(
p
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
WINDOW_NOT_FOUND_1
,
parent
);
}
p
.
resolveWindows
(
resolver
);
if
(
partitionBy
==
null
)
{
partitionBy
=
p
.
partitionBy
;
}
if
(
orderBy
==
null
)
{
orderBy
=
p
.
orderBy
;
}
if
(
frame
==
null
)
{
frame
=
p
.
frame
;
}
parent
=
null
;
}
}
/**
* Try to optimize the window conditions.
*
...
...
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
浏览文件 @
8863b2db
...
...
@@ -1549,7 +1549,7 @@ public class JdbcDatabaseMetaData extends TraceObject implements
* HAVING, INNER, INTERSECT, INTERSECTS, IS, JOIN, LIKE, LIMIT, LOCALTIME,
* LOCALTIMESTAMP, MINUS, NATURAL, NOT, NULL, OFFSET, ON, ORDER, PRIMARY, ROWNUM,
* SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TOP, TRUE, UNION, UNIQUE, WHERE,
* WITH
* WI
NDOW, WI
TH
* </pre>
*
* @return a list of additional the keywords
...
...
h2/src/main/org/h2/message/DbException.java
浏览文件 @
8863b2db
...
...
@@ -562,6 +562,7 @@ public class DbException extends RuntimeException {
case
CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS:
case
TRANSACTION_NOT_FOUND_1:
case
AGGREGATE_NOT_FOUND_1:
case
WINDOW_NOT_FOUND_1:
case
CAN_ONLY_ASSIGN_TO_VARIABLE_1:
case
PUBLIC_STATIC_JAVA_METHOD_NOT_FOUND_1:
case
JAVA_OBJECT_SERIALIZER_CHANGE_WITH_DATA_TABLE:
...
...
h2/src/main/org/h2/res/_messages_cs.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Nelze změnit nastavení {0}, pokud je již databáze otevřena
90134=Přístup ke třídě {0} byl odepřen
90135=Databáze je spuštěna ve vyhrazeném režimu; nelze otevřít další spojení
90136=
Nepodporovaná podmínka vnějšího spojení
: {0}
90136=
#Window not found
: {0}
90137=Lze přiřadit pouze proměnné, nikoli: {0}
90138=Neplatný název databáze: {0}
90139=Nenalezena veřejná statická Java metoda: {0}
...
...
h2/src/main/org/h2/res/_messages_de.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Kann das Setting {0} nicht ändern wenn die Datenbank bereits geöffnet ist
90134=Der Zugriff auf die Klasse {0} ist nicht erlaubt
90135=Die Datenbank befindet sich im Exclusiv Modus; es können keine zusätzlichen Verbindungen geöffnet werden
90136=
Diese Outer Join Bedingung wird nicht unterstützt
: {0}
90136=
#Window not found
: {0}
90137=Werte können nur einer Variablen zugewiesen werden, nicht an: {0}
90138=Ungültiger Datenbank Name: {0}
90139=Die (public static) Java Funktion wurde nicht gefunden: {0}
...
...
h2/src/main/org/h2/res/_messages_en.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Cannot change the setting {0} when the database is already open
90134=Access to the class {0} is denied
90135=The database is open in exclusive mode; can not open additional connections
90136=
Unsupported outer join condition
: {0}
90136=
Window not found
: {0}
90137=Can only assign to a variable, not to: {0}
90138=Invalid database name: {0}
90139=The public static Java method was not found: {0}
...
...
h2/src/main/org/h2/res/_messages_es.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=No puede cambiar el setting {0} cuando la base de datos esta abierta
90134=Acceso denegado a la clase {0}
90135=La base de datos esta abierta en modo EXCLUSIVO; no puede abrir conexiones adicionales
90136=
Condición No soportada en Outer join
: {0}
90136=
#Window not found
: {0}
90137=Solo puede asignarse a una variable, no a: {0}
90138=Nombre de base de datos Invalido: {0}
90139=El metodo Java (publico y estatico) : {0} no fue encontrado
...
...
h2/src/main/org/h2/res/_messages_fr.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Impossible de changer le paramétrage {0} lorsque la base de données est déjà ouverte
90134=L''accès à la classe {0} est interdit
90135=La base de données est ouverte en mode exclusif; impossible d''ouvrir des connexions additionnelles
90136=
Condition de jointure extérieure non prise en charge
: {0}
90136=
#Window not found
: {0}
90137=Peut seulement être assigné à une variable, pas à: {0}
90138=Nom de la base de données invalide: {0}
90139=La méthode Java public static n''a pas été trouvée: {0}
...
...
h2/src/main/org/h2/res/_messages_ja.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=データベースオープン中には、設定 {0} を変更できません
90134=クラス {0} へのアクセスが拒否されました
90135=データベースは排他モードでオープンされています; 接続を追加することはできません
90136=
未サポートの外部結合条件
: {0}
90136=
#Window not found
: {0}
90137=割り当ては変数にのみ可能です。{0} にはできません
90138=不正なデータベース名: {0}
90139=public staticであるJavaメソッドが見つかりません: {0}
...
...
h2/src/main/org/h2/res/_messages_pl.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Nie można zmienić ustawienia {0} gdy baza danych jest otwarta
90134=Dostęp do klasy {0} jest zabroniony
90135=Baza danych jest otwarta w trybie wyłączności, nie można otworzyć dodatkowych połączeń
90136=
Nieobsługiwany warunek złączenia zewnętrznego
: {0}
90136=
#Window not found
: {0}
90137=Można przypisywać tylko do zmiennych, nie do: {0}
90138=Nieprawidłowa nazwa bazy danych: {0}
90139=Publiczna, statyczna metoda Java nie znaleziona: {0}
...
...
h2/src/main/org/h2/res/_messages_pt_br.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=#Cannot change the setting {0} when the database is already open
90134=#Access to the class {0} is denied
90135=#The database is open in exclusive mode; can not open additional connections
90136=#
Unsupported outer join condition
: {0}
90136=#
Window not found
: {0}
90137=#Can only assign to a variable, not to: {0}
90138=#Invalid database name: {0}
90139=#The public static Java method was not found: {0}
...
...
h2/src/main/org/h2/res/_messages_ru.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Невозможно изменить опцию {0}, когда база данных уже открыта
90134=Доступ к классу {0} запрещен
90135=База данных открыта в эксклюзивном режиме, открыть дополнительные соединения невозможно
90136=
Данное условие не поддерживается в OUTER JOIN
: {0}
90136=
Окно не найдено
: {0}
90137=Присваивать значения возможно только переменным, но не: {0}
90138=Недопустимое имя базы данных: {0}
90139=public static Java метод не найден: {0}
...
...
h2/src/main/org/h2/res/_messages_sk.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=Nemôžem zmeniť nastavenie {0} keď už je databáza otvorená
90134=Prístup k triede {0} odoprený
90135=Databáza je otvorená vo výhradnom (exclusive) móde; nemôžem na ňu otvoriť ďalšie pripojenia
90136=
Nepodporovaná "outer join" podmienka
: {0}
90136=
#Window not found
: {0}
90137=Môžete priradiť len do premennej, nie do: {0}
90138=Nesprávne meno databázy: {0}
90139=Verejná statická Java metóda nebola nájdená: {0}
...
...
h2/src/main/org/h2/res/_messages_zh_cn.prop
浏览文件 @
8863b2db
...
...
@@ -166,7 +166,7 @@
90133=数据库有已启动的时候不允许更改设置{0}
90134=访问 {0}类时被拒绝
90135=数据库运行在独占模式(exclusive mode); 不能打开额外的连接
90136=
不支持的外连接条件
: {0}
90136=
#Window not found
: {0}
90137=只能赋值到一个变量,而不是: {0}
90138=无效数据库名称: {0}
90139=找不到公用Java静态方法: {0}
...
...
h2/src/main/org/h2/util/ParserUtil.java
浏览文件 @
8863b2db
...
...
@@ -207,10 +207,15 @@ public class ParserUtil {
*/
public
static
final
int
WHERE
=
UNIQUE
+
1
;
/**
* The token "WINDOW".
*/
public
static
final
int
WINDOW
=
WHERE
+
1
;
/**
* The token "WITH".
*/
public
static
final
int
WITH
=
W
HERE
+
1
;
public
static
final
int
WITH
=
W
INDOW
+
1
;
private
static
final
int
UPPER_OR_OTHER_LETTER
=
1
<<
Character
.
UPPERCASE_LETTER
...
...
@@ -426,10 +431,12 @@ public class ParserUtil {
}
return
IDENTIFIER
;
case
'W'
:
if
(
"WITH"
.
equals
(
s
))
{
return
WITH
;
}
else
if
(
"WHERE"
.
equals
(
s
))
{
if
(
"WHERE"
.
equals
(
s
))
{
return
WHERE
;
}
else
if
(
"WINDOW"
.
equals
(
s
))
{
return
WINDOW
;
}
else
if
(
"WITH"
.
equals
(
s
))
{
return
WITH
;
}
return
IDENTIFIER
;
default
:
...
...
h2/src/test/org/h2/test/scripts/TestScript.java
浏览文件 @
8863b2db
...
...
@@ -110,6 +110,7 @@ public class TestScript extends TestDb {
testScript
(
"altertable-fk.sql"
);
testScript
(
"default-and-on_update.sql"
);
testScript
(
"query-optimisations.sql"
);
testScript
(
"window.sql"
);
String
decimal2
;
if
(
SysProperties
.
BIG_DECIMAL_IS_DECIMAL
)
{
decimal2
=
"decimal_decimal"
;
...
...
h2/src/test/org/h2/test/scripts/window.sql
0 → 100644
浏览文件 @
8863b2db
-- 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
--
CREATE
TABLE
TEST
(
ID
INT
,
R
INT
,
CATEGORY
INT
);
>
ok
INSERT
INTO
TEST
VALUES
(
1
,
4
,
1
),
(
2
,
3
,
1
),
(
3
,
2
,
2
),
(
4
,
1
,
2
);
>
update
count
:
4
SELECT
*
,
ROW_NUMBER
()
OVER
W
FROM
TEST
;
>
exception
WINDOW_NOT_FOUND_1
SELECT
*
FROM
TEST
WINDOW
W
AS
W1
,
W1
AS
();
>
exception
SYNTAX_ERROR_2
SELECT
*
,
ROW_NUMBER
()
OVER
W1
,
ROW_NUMBER
()
OVER
W2
FROM
TEST
WINDOW
W1
AS
(
W2
ORDER
BY
ID
),
W2
AS
(
PARTITION
BY
CATEGORY
ORDER
BY
ID
DESC
);
>
ID
R
CATEGORY
ROW_NUMBER
()
OVER
(
PARTITION
BY
CATEGORY
ORDER
BY
ID
)
ROW_NUMBER
()
OVER
(
PARTITION
BY
CATEGORY
ORDER
BY
ID
DESC
)
>
-- - -------- ----------------------------------------------------- ----------------------------------------------------------
>
1
4
1
1
2
>
2
3
1
2
1
>
3
2
2
1
2
>
4
1
2
2
1
>
rows
(
ordered
):
4
SELECT
*
,
LAST_VALUE
(
ID
)
OVER
W
FROM
TEST
WINDOW
W
AS
(
PARTITION
BY
CATEGORY
ORDER
BY
ID
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
EXCLUDE
CURRENT
ROW
);
>
ID
R
CATEGORY
LAST_VALUE
(
ID
)
OVER
(
PARTITION
BY
CATEGORY
ORDER
BY
ID
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
EXCLUDE
CURRENT
ROW
)
>
-- - -------- -------------------------------------------------------------------------------------------------------------------------------------
>
1
4
1
2
>
2
3
1
1
>
3
2
2
4
>
4
1
2
3
>
rows
(
ordered
):
4
DROP
TABLE
TEST
;
>
ok
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论