Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ba358f48
提交
ba358f48
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Evaluate window aggregates only once for each partition
上级
3b296bb7
master
version-1.4.198
无相关合并请求
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
222 行增加
和
61 行删除
+222
-61
AbstractAggregate.java
...c/main/org/h2/expression/aggregate/AbstractAggregate.java
+85
-18
Aggregate.java
h2/src/main/org/h2/expression/aggregate/Aggregate.java
+35
-34
JavaAggregate.java
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
+3
-8
PartitionData.java
h2/src/main/org/h2/expression/aggregate/PartitionData.java
+63
-0
array-agg.sql
...est/org/h2/test/scripts/functions/aggregate/array-agg.sql
+36
-1
没有找到文件。
h2/src/main/org/h2/expression/aggregate/AbstractAggregate.java
浏览文件 @
ba358f48
...
...
@@ -5,13 +5,16 @@
*/
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
/**
...
...
@@ -137,8 +140,9 @@ public abstract class AbstractAggregate extends Expression {
protected
Object
getData
(
Session
session
,
SelectGroups
groupData
,
boolean
ifExists
)
{
Object
data
;
ValueArray
key
;
if
(
over
!=
null
&&
(
key
=
over
.
getCurrentKey
(
session
))
!=
null
)
{
if
(
over
!=
null
)
{
ValueArray
key
=
over
.
getCurrentKey
(
session
);
if
(
key
!=
null
)
{
@SuppressWarnings
(
"unchecked"
)
ValueHashMap
<
Object
>
map
=
(
ValueHashMap
<
Object
>)
groupData
.
getCurrentGroupExprData
(
this
,
true
);
if
(
map
==
null
)
{
...
...
@@ -148,22 +152,36 @@ public abstract class AbstractAggregate extends Expression {
map
=
new
ValueHashMap
<>();
groupData
.
setCurrentGroupExprData
(
this
,
map
,
true
);
}
data
=
map
.
get
(
key
);
if
(
data
==
null
)
{
PartitionData
partition
=
(
PartitionData
)
map
.
get
(
key
);
if
(
partition
==
null
)
{
if
(
ifExists
)
{
return
null
;
}
data
=
createAggregateData
();
map
.
put
(
key
,
new
PartitionData
(
data
));
}
else
{
data
=
partition
.
getData
();
}
}
else
{
PartitionData
partition
=
(
PartitionData
)
groupData
.
getCurrentGroupExprData
(
this
,
true
);
if
(
partition
==
null
)
{
if
(
ifExists
)
{
return
null
;
}
data
=
createAggregateData
();
map
.
put
(
key
,
data
);
groupData
.
setCurrentGroupExprData
(
this
,
new
PartitionData
(
data
),
true
);
}
else
{
data
=
partition
.
getData
();
}
}
}
else
{
data
=
groupData
.
getCurrentGroupExprData
(
this
,
over
!=
null
);
data
=
groupData
.
getCurrentGroupExprData
(
this
,
false
);
if
(
data
==
null
)
{
if
(
ifExists
)
{
return
null
;
}
data
=
createAggregateData
();
groupData
.
setCurrentGroupExprData
(
this
,
data
,
over
!=
null
);
groupData
.
setCurrentGroupExprData
(
this
,
data
,
false
);
}
}
return
data
;
...
...
@@ -171,6 +189,55 @@ public abstract class AbstractAggregate extends Expression {
protected
abstract
Object
createAggregateData
();
@Override
public
Value
getValue
(
Session
session
)
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
(
over
!=
null
);
if
(
groupData
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
}
return
over
==
null
?
getAggregatedValue
(
session
,
getData
(
session
,
groupData
,
true
))
:
getWindowResult
(
session
,
groupData
);
}
private
Value
getWindowResult
(
Session
session
,
SelectGroups
groupData
)
{
PartitionData
partition
;
Object
data
;
ValueArray
key
=
over
.
getCurrentKey
(
session
);
if
(
key
!=
null
)
{
@SuppressWarnings
(
"unchecked"
)
ValueHashMap
<
Object
>
map
=
(
ValueHashMap
<
Object
>)
groupData
.
getCurrentGroupExprData
(
this
,
true
);
if
(
map
==
null
)
{
map
=
new
ValueHashMap
<>();
groupData
.
setCurrentGroupExprData
(
this
,
map
,
true
);
}
partition
=
(
PartitionData
)
map
.
get
(
key
);
if
(
partition
==
null
)
{
data
=
createAggregateData
();
partition
=
new
PartitionData
(
data
);
map
.
put
(
key
,
partition
);
}
else
{
data
=
partition
.
getData
();
}
}
else
{
partition
=
(
PartitionData
)
groupData
.
getCurrentGroupExprData
(
this
,
true
);
if
(
partition
==
null
)
{
data
=
createAggregateData
();
partition
=
new
PartitionData
(
data
);
groupData
.
setCurrentGroupExprData
(
this
,
partition
,
true
);
}
else
{
data
=
partition
.
getData
();
}
}
Value
result
=
partition
.
getResult
();
if
(
result
==
null
)
{
result
=
getAggregatedValue
(
session
,
data
);
partition
.
setResult
(
result
);
}
return
result
;
}
protected
abstract
Value
getAggregatedValue
(
Session
session
,
Object
aggregateData
);
protected
StringBuilder
appendTailConditions
(
StringBuilder
builder
)
{
if
(
filterCondition
!=
null
)
{
builder
.
append
(
" FILTER (WHERE "
).
append
(
filterCondition
.
getSQL
()).
append
(
')'
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/Aggregate.java
浏览文件 @
ba358f48
...
...
@@ -11,7 +11,6 @@ import java.util.Comparator;
import
java.util.HashMap
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
...
...
@@ -332,7 +331,10 @@ public class Aggregate extends AbstractAggregate {
@Override
public
Value
getValue
(
Session
session
)
{
if
(
select
.
isQuickAggregateQuery
())
{
return
select
.
isQuickAggregateQuery
()
?
getValueQuick
(
session
)
:
super
.
getValue
(
session
);
}
private
Value
getValueQuick
(
Session
session
)
{
switch
(
type
)
{
case
COUNT:
case
COUNT_ALL:
...
...
@@ -361,14 +363,13 @@ public class Aggregate extends AbstractAggregate {
case
ENVELOPE:
return
((
MVSpatialIndex
)
AggregateDataEnvelope
.
getGeometryColumnIndex
(
on
)).
getBounds
(
session
);
default
:
DbException
.
throwInternalError
(
"type="
+
type
);
}
throw
DbException
.
throwInternalError
(
"type="
+
type
);
}
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
(
over
!=
null
);
if
(
groupData
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
}
AggregateData
data
=
(
AggregateData
)
getData
(
session
,
groupData
,
true
);
@Override
public
Value
getAggregatedValue
(
Session
session
,
Object
aggregateData
)
{
AggregateData
data
=
(
AggregateData
)
aggregateData
;
if
(
data
==
null
)
{
data
=
(
AggregateData
)
createAggregateData
();
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
浏览文件 @
ba358f48
...
...
@@ -8,7 +8,6 @@ package org.h2.expression.aggregate;
import
java.sql.Connection
;
import
java.sql.SQLException
;
import
org.h2.api.Aggregate
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.Parser
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
...
...
@@ -158,16 +157,12 @@ public class JavaAggregate extends AbstractAggregate {
}
@Override
public
Value
getValue
(
Session
session
)
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
(
over
!=
null
);
if
(
groupData
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
}
public
Value
getAggregatedValue
(
Session
session
,
Object
aggregateData
)
{
try
{
Aggregate
agg
;
if
(
distinct
)
{
agg
=
getInstance
();
AggregateDataCollecting
data
=
(
AggregateDataCollecting
)
getData
(
session
,
groupData
,
true
)
;
AggregateDataCollecting
data
=
(
AggregateDataCollecting
)
aggregateData
;
if
(
data
!=
null
)
{
for
(
Value
value
:
data
.
values
)
{
if
(
args
.
length
==
1
)
{
...
...
@@ -183,7 +178,7 @@ public class JavaAggregate extends AbstractAggregate {
}
}
}
else
{
agg
=
(
Aggregate
)
getData
(
session
,
groupData
,
true
)
;
agg
=
(
Aggregate
)
aggregateData
;
if
(
agg
==
null
)
{
agg
=
getInstance
();
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/PartitionData.java
0 → 100644
浏览文件 @
ba358f48
/*
* 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.value.Value
;
/**
* Partition data of a window aggregate.
*/
final
class
PartitionData
{
/**
* Aggregate data.
*/
private
final
Object
data
;
/**
* Evaluated result.
*/
private
Value
result
;
/**
* Creates new instance of partition data.
*
* @param data
* aggregate data
*/
PartitionData
(
Object
data
)
{
this
.
data
=
data
;
}
/**
* Returns the aggregate data.
*
* @return the aggregate data
*/
Object
getData
()
{
return
data
;
}
/**
* Returns the result.
*
* @return the result
*/
Value
getResult
()
{
return
result
;
}
/**
* Sets the result.
*
* @param result
* the result to set
*/
void
setResult
(
Value
result
)
{
this
.
result
=
result
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/aggregate/array-agg.sql
浏览文件 @
ba358f48
...
...
@@ -151,13 +151,48 @@ SELECT ARRAY_AGG(ARRAY_AGG(ID ORDER /**/ BY ID)) OVER (PARTITION BY NAME), NAME
>
((
4
,
5
,
6
))
c
>
rows
:
3
SELECT
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
/**/
BY
ID
))
OVER
(
PARTITION
BY
NAME
),
NAME
FROM
TEST
GROUP
BY
NAME
ORDER
/**/
BY
NAME
OFFSET
1
ROW
;
SELECT
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
/**/
BY
ID
))
OVER
(
PARTITION
BY
NAME
),
NAME
FROM
TEST
GROUP
BY
NAME
ORDER
/**/
BY
NAME
OFFSET
1
ROW
;
>
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
OVER
(
PARTITION
BY
NAME
)
NAME
>
------------------------------------------------------------- ----
>
((
3
))
b
>
((
4
,
5
,
6
))
c
>
rows
:
2
SELECT
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
NAME
>
'b'
)
OVER
(
PARTITION
BY
NAME
),
NAME
FROM
TEST
GROUP
BY
NAME
ORDER
BY
NAME
;
>
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
(
NAME
>
'b'
))
OVER
(
PARTITION
BY
NAME
)
NAME
>
----------------------------------------------------------------------------------------- ----
>
null
a
>
null
b
>
((
4
,
5
,
6
))
c
>
rows
(
ordered
):
3
SELECT
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
NAME
>
'c'
)
OVER
(
PARTITION
BY
NAME
),
NAME
FROM
TEST
GROUP
BY
NAME
ORDER
BY
NAME
;
>
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
(
NAME
>
'c'
))
OVER
(
PARTITION
BY
NAME
)
NAME
>
----------------------------------------------------------------------------------------- ----
>
null
a
>
null
b
>
null
c
>
rows
(
ordered
):
3
SELECT
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
NAME
>
'b'
)
OVER
()
FROM
TEST
GROUP
BY
NAME
ORDER
BY
NAME
;
>
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
(
NAME
>
'b'
))
OVER
()
>
------------------------------------------------------------------------
>
((
4
,
5
,
6
))
>
((
4
,
5
,
6
))
>
((
4
,
5
,
6
))
>
rows
(
ordered
):
3
SELECT
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
NAME
>
'c'
)
OVER
()
FROM
TEST
GROUP
BY
NAME
ORDER
BY
NAME
;
>
ARRAY_AGG
(
ARRAY_AGG
(
ID
ORDER
BY
ID
))
FILTER
(
WHERE
(
NAME
>
'c'
))
OVER
()
>
------------------------------------------------------------------------
>
null
>
null
>
null
>
rows
(
ordered
):
3
SELECT
ARRAY_AGG
(
ID
)
OVER
()
FROM
TEST
GROUP
BY
NAME
;
>
exception
MUST_GROUP_BY_COLUMN_1
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论