Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
7dc28ecd
Unverified
提交
7dc28ecd
authored
6 年前
作者:
Evgenij Ryazanov
提交者:
GitHub
6 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1705 from katzyn/aggregate
Fix GROUP_CONCAT with variable separator
上级
b27b12be
c32e8dc1
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
131 行增加
和
121 行删除
+131
-121
help.csv
h2/src/docsrc/help/help.csv
+1
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+22
-15
AbstractAggregate.java
...c/main/org/h2/expression/aggregate/AbstractAggregate.java
+27
-1
Aggregate.java
h2/src/main/org/h2/expression/aggregate/Aggregate.java
+50
-75
JavaAggregate.java
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
+2
-30
group-concat.sql
.../org/h2/test/scripts/functions/aggregate/group-concat.sql
+29
-0
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
7dc28ecd
...
...
@@ -3545,6 +3545,7 @@ GROUP_CONCAT ( [ DISTINCT|ALL ] string
[FILTER (WHERE expression)] [OVER windowNameOrSpecification]
","
Concatenates strings with a separator.
Separator must be the same for all rows in the same group.
The default separator is a ',' (without space).
This method returns a string.
If no rows are selected, the result is NULL.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/Parser.java
浏览文件 @
7dc28ecd
...
...
@@ -3041,43 +3041,50 @@ public class Parser {
switch
(
aggregateType
)
{
case
COUNT:
if
(
readIf
(
ASTERISK
))
{
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
n
ull
,
currentSelect
,
false
);
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
n
ew
Expression
[
0
]
,
currentSelect
,
false
);
}
else
{
boolean
distinct
=
readDistinctAgg
();
Expression
on
=
readExpression
();
if
(
on
instanceof
Wildcard
&&
!
distinct
)
{
// PostgreSQL compatibility: count(t.*)
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
n
ull
,
currentSelect
,
false
);
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
n
ew
Expression
[
0
]
,
currentSelect
,
false
);
}
else
{
r
=
new
Aggregate
(
AggregateType
.
COUNT
,
on
,
currentSelect
,
distinct
);
r
=
new
Aggregate
(
AggregateType
.
COUNT
,
new
Expression
[]
{
on
}
,
currentSelect
,
distinct
);
}
}
break
;
case
GROUP_CONCAT:
{
boolean
distinct
=
readDistinctAgg
();
r
=
new
Aggregate
(
AggregateType
.
GROUP_CONCAT
,
readExpression
(),
currentSelect
,
distinct
);
Expression
arg
=
readExpression
(),
separator
=
null
;
ArrayList
<
SelectOrderBy
>
orderByList
=
null
;
if
(
equalsToken
(
"STRING_AGG"
,
aggregateName
))
{
// PostgreSQL compatibility: string_agg(expression, delimiter)
read
(
COMMA
);
r
.
setGroupConcatSeparator
(
readExpression
()
);
separator
=
readExpression
(
);
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
r
.
setOrderByList
(
parseSimpleOrderList
()
);
orderByList
=
parseSimpleOrderList
(
);
}
}
else
{
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
r
.
setOrderByList
(
parseSimpleOrderList
()
);
orderByList
=
parseSimpleOrderList
(
);
}
if
(
readIf
(
"SEPARATOR"
))
{
r
.
setGroupConcatSeparator
(
readExpression
()
);
separator
=
readExpression
(
);
}
}
r
=
new
Aggregate
(
AggregateType
.
GROUP_CONCAT
,
separator
==
null
?
new
Expression
[]
{
arg
}
:
new
Expression
[]
{
arg
,
separator
},
currentSelect
,
distinct
);
if
(
orderByList
!=
null
)
{
r
.
setOrderByList
(
orderByList
);
}
break
;
}
case
ARRAY_AGG:
{
boolean
distinct
=
readDistinctAgg
();
r
=
new
Aggregate
(
AggregateType
.
ARRAY_AGG
,
readExpression
()
,
currentSelect
,
distinct
);
r
=
new
Aggregate
(
AggregateType
.
ARRAY_AGG
,
new
Expression
[]
{
readExpression
()
}
,
currentSelect
,
distinct
);
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
r
.
setOrderByList
(
parseSimpleOrderList
());
...
...
@@ -3088,15 +3095,15 @@ public class Parser {
case
PERCENTILE_DISC:
{
Expression
num
=
readExpression
();
read
(
CLOSE_PAREN
);
r
=
readWithinGroup
(
aggregateType
,
n
um
);
r
=
readWithinGroup
(
aggregateType
,
n
ew
Expression
[]
{
num
}
);
break
;
}
case
MODE:
{
if
(
readIf
(
CLOSE_PAREN
))
{
r
=
readWithinGroup
(
AggregateType
.
MODE
,
n
ull
);
r
=
readWithinGroup
(
AggregateType
.
MODE
,
n
ew
Expression
[
0
]
);
}
else
{
Expression
expr
=
readExpression
();
r
=
new
Aggregate
(
aggregateType
,
n
ull
,
currentSelect
,
false
);
r
=
new
Aggregate
(
aggregateType
,
n
ew
Expression
[
0
]
,
currentSelect
,
false
);
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
Expression
expr2
=
readExpression
();
...
...
@@ -3114,7 +3121,7 @@ public class Parser {
}
default
:
boolean
distinct
=
readDistinctAgg
();
r
=
new
Aggregate
(
aggregateType
,
readExpression
()
,
currentSelect
,
distinct
);
r
=
new
Aggregate
(
aggregateType
,
new
Expression
[]
{
readExpression
()
}
,
currentSelect
,
distinct
);
break
;
}
read
(
CLOSE_PAREN
);
...
...
@@ -3122,7 +3129,7 @@ public class Parser {
return
r
;
}
private
Aggregate
readWithinGroup
(
AggregateType
aggregateType
,
Expression
argument
)
{
private
Aggregate
readWithinGroup
(
AggregateType
aggregateType
,
Expression
[]
args
)
{
Aggregate
r
;
read
(
"WITHIN"
);
read
(
GROUP
);
...
...
@@ -3130,7 +3137,7 @@ public class Parser {
read
(
ORDER
);
read
(
"BY"
);
Expression
expr
=
readExpression
();
r
=
new
Aggregate
(
aggregateType
,
arg
ument
,
currentSelect
,
false
);
r
=
new
Aggregate
(
aggregateType
,
arg
s
,
currentSelect
,
false
);
readAggregateOrder
(
r
,
expr
,
true
);
return
r
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/AbstractAggregate.java
浏览文件 @
7dc28ecd
...
...
@@ -22,6 +22,7 @@ import org.h2.expression.analysis.WindowFrameExclusion;
import
org.h2.expression.analysis.WindowFrameUnits
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.value.TypeInfo
;
import
org.h2.value.Value
;
/**
...
...
@@ -34,13 +35,24 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
*/
protected
final
boolean
distinct
;
/**
* The arguments.
*/
protected
final
Expression
[]
args
;
/**
* FILTER condition for aggregate
*/
protected
Expression
filterCondition
;
AbstractAggregate
(
Select
select
,
boolean
distinct
)
{
/**
* The type of the result.
*/
protected
TypeInfo
type
;
AbstractAggregate
(
Select
select
,
Expression
[]
args
,
boolean
distinct
)
{
super
(
select
);
this
.
args
=
args
;
this
.
distinct
=
distinct
;
}
...
...
@@ -59,8 +71,16 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
this
.
filterCondition
=
filterCondition
;
}
@Override
public
TypeInfo
getType
()
{
return
type
;
}
@Override
public
void
mapColumnsAnalysis
(
ColumnResolver
resolver
,
int
level
,
int
innerState
)
{
for
(
Expression
arg
:
args
)
{
arg
.
mapColumns
(
resolver
,
level
,
innerState
);
}
if
(
filterCondition
!=
null
)
{
filterCondition
.
mapColumns
(
resolver
,
level
,
innerState
);
}
...
...
@@ -69,6 +89,9 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
@Override
public
Expression
optimize
(
Session
session
)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
args
[
i
]
=
args
[
i
].
optimize
(
session
);
}
if
(
filterCondition
!=
null
)
{
filterCondition
=
filterCondition
.
optimize
(
session
);
}
...
...
@@ -77,6 +100,9 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
@Override
public
void
setEvaluatable
(
TableFilter
tableFilter
,
boolean
b
)
{
for
(
Expression
arg
:
args
)
{
arg
.
setEvaluatable
(
tableFilter
,
b
);
}
if
(
filterCondition
!=
null
)
{
filterCondition
.
setEvaluatable
(
tableFilter
,
b
);
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/Aggregate.java
浏览文件 @
7dc28ecd
差异被折叠。
点击展开。
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
浏览文件 @
7dc28ecd
...
...
@@ -15,8 +15,6 @@ import org.h2.engine.UserAggregate;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.message.DbException
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.value.DataType
;
import
org.h2.value.TypeInfo
;
import
org.h2.value.Value
;
...
...
@@ -30,16 +28,13 @@ import org.h2.value.ValueRow;
public
class
JavaAggregate
extends
AbstractAggregate
{
private
final
UserAggregate
userAggregate
;
private
final
Expression
[]
args
;
private
int
[]
argTypes
;
private
TypeInfo
type
;
private
int
dataType
;
private
Connection
userConnection
;
public
JavaAggregate
(
UserAggregate
userAggregate
,
Expression
[]
args
,
Select
select
,
boolean
distinct
)
{
super
(
select
,
distinct
);
super
(
select
,
args
,
distinct
);
this
.
userAggregate
=
userAggregate
;
this
.
args
=
args
;
}
@Override
...
...
@@ -62,11 +57,6 @@ public class JavaAggregate extends AbstractAggregate {
return
appendTailConditions
(
builder
);
}
@Override
public
TypeInfo
getType
()
{
return
type
;
}
@Override
public
boolean
isEverything
(
ExpressionVisitor
visitor
)
{
if
(!
super
.
isEverything
(
visitor
))
{
...
...
@@ -92,14 +82,6 @@ public class JavaAggregate extends AbstractAggregate {
return
filterCondition
==
null
||
filterCondition
.
isEverything
(
visitor
);
}
@Override
public
void
mapColumnsAnalysis
(
ColumnResolver
resolver
,
int
level
,
int
innerState
)
{
for
(
Expression
arg
:
args
)
{
arg
.
mapColumns
(
resolver
,
level
,
innerState
);
}
super
.
mapColumnsAnalysis
(
resolver
,
level
,
innerState
);
}
@Override
public
Expression
optimize
(
Session
session
)
{
super
.
optimize
(
session
);
...
...
@@ -107,9 +89,7 @@ public class JavaAggregate extends AbstractAggregate {
int
len
=
args
.
length
;
argTypes
=
new
int
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Expression
expr
=
args
[
i
];
args
[
i
]
=
expr
.
optimize
(
session
);
int
type
=
expr
.
getType
().
getValueType
();
int
type
=
args
[
i
].
getType
().
getValueType
();
argTypes
[
i
]
=
type
;
}
try
{
...
...
@@ -122,14 +102,6 @@ public class JavaAggregate extends AbstractAggregate {
return
this
;
}
@Override
public
void
setEvaluatable
(
TableFilter
tableFilter
,
boolean
b
)
{
for
(
Expression
e
:
args
)
{
e
.
setEvaluatable
(
tableFilter
,
b
);
}
super
.
setEvaluatable
(
tableFilter
,
b
);
}
private
Aggregate
getInstance
()
{
Aggregate
agg
=
userAggregate
.
getInstance
();
try
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/aggregate/group-concat.sql
浏览文件 @
7dc28ecd
...
...
@@ -67,3 +67,32 @@ select group_concat(distinct v order by v desc) from test;
drop
table
test
;
>
ok
create
table
test
(
g
varchar
,
v
int
)
as
values
(
'-'
,
1
),
(
'-'
,
2
),
(
'-'
,
3
),
(
'|'
,
4
),
(
'|'
,
5
),
(
'|'
,
6
),
(
'*'
,
null
);
>
ok
select
g
,
group_concat
(
v
separator
g
)
from
test
group
by
g
;
>
G
GROUP_CONCAT
(
V
SEPARATOR
G
)
>
-
---------------------------
>
*
null
>
-
1
-
2
-
3
>
|
4
|
5
|
6
>
rows
:
3
select
g
,
group_concat
(
v
separator
g
)
over
(
partition
by
g
)
from
test
order
by
v
;
>
G
GROUP_CONCAT
(
V
SEPARATOR
G
)
OVER
(
PARTITION
BY
G
)
>
-
-------------------------------------------------
>
*
null
>
-
1
-
2
-
3
>
-
1
-
2
-
3
>
-
1
-
2
-
3
>
|
4
|
5
|
6
>
|
4
|
5
|
6
>
|
4
|
5
|
6
>
rows
(
ordered
):
7
select
g
,
group_concat
(
v
separator
v
)
from
test
group
by
g
;
>
exception
INVALID_VALUE_2
drop
table
test
;
>
ok
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论