Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
8323369e
提交
8323369e
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Extract SelectGroups from Select
上级
92d7f561
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
292 行增加
和
133 行删除
+292
-133
Select.java
h2/src/main/org/h2/command/dml/Select.java
+23
-112
SelectGroups.java
h2/src/main/org/h2/command/dml/SelectGroups.java
+239
-0
ExpressionColumn.java
h2/src/main/org/h2/expression/ExpressionColumn.java
+8
-5
Aggregate.java
h2/src/main/org/h2/expression/aggregate/Aggregate.java
+10
-7
JavaAggregate.java
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
+12
-9
没有找到文件。
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
8323369e
...
@@ -8,9 +8,7 @@ package org.h2.command.dml;
...
@@ -8,9 +8,7 @@ package org.h2.command.dml;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
java.util.BitSet
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.Map
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.Trigger
;
import
org.h2.api.Trigger
;
import
org.h2.command.Parser
;
import
org.h2.command.Parser
;
...
@@ -103,23 +101,7 @@ public class Select extends Query {
...
@@ -103,23 +101,7 @@ public class Select extends Query {
*/
*/
boolean
[]
groupByExpression
;
boolean
[]
groupByExpression
;
/**
SelectGroups
groupData
;
* The array of current group-by expression data e.g. AggregateData.
*/
Object
[]
currentGroupByExprData
;
/**
* Maps an expression object to an index, to use in accessing the Object[]
* pointed to by groupByData.
*/
final
HashMap
<
Expression
,
Integer
>
exprToIndexInGroupByData
=
new
HashMap
<>();
/**
* Map of group-by key to group-by expression data e.g. AggregateData
*/
private
HashMap
<
Value
,
Object
[]>
groupByData
;
/**
* Key into groupByData that produces currentGroupByExprData. Not used in lazy mode.
*/
ValueArray
currentGroupsKey
;
private
int
havingIndex
;
private
int
havingIndex
;
private
boolean
isGroupQuery
,
isGroupSortedQuery
;
private
boolean
isGroupQuery
,
isGroupSortedQuery
;
...
@@ -129,11 +111,6 @@ public class Select extends Query {
...
@@ -129,11 +111,6 @@ public class Select extends Query {
private
boolean
isPrepared
,
checkInit
;
private
boolean
isPrepared
,
checkInit
;
private
boolean
sortUsingIndex
;
private
boolean
sortUsingIndex
;
/**
* The id of the current group.
*/
int
currentGroupRowId
;
public
Select
(
Session
session
)
{
public
Select
(
Session
session
)
{
super
(
session
);
super
(
session
);
}
}
...
@@ -191,49 +168,8 @@ public class Select extends Query {
...
@@ -191,49 +168,8 @@ public class Select extends Query {
return
group
;
return
group
;
}
}
/**
public
SelectGroups
getGroupDataIfCurrent
()
{
* Is there currently a group-by active
return
groupData
!=
null
&&
groupData
.
isCurrentGroup
()
?
groupData
:
null
;
*/
public
boolean
isCurrentGroup
()
{
return
currentGroupByExprData
!=
null
;
}
/**
* Get the group-by data for the current group and the passed in expression.
*/
public
Object
getCurrentGroupExprData
(
Expression
expr
)
{
Integer
index
=
exprToIndexInGroupByData
.
get
(
expr
);
if
(
index
==
null
)
{
return
null
;
}
return
currentGroupByExprData
[
index
];
}
/**
* Set the group-by data for the current group and the passed in expression.
*/
public
void
setCurrentGroupExprData
(
Expression
expr
,
Object
obj
)
{
Integer
index
=
exprToIndexInGroupByData
.
get
(
expr
);
if
(
index
!=
null
)
{
assert
currentGroupByExprData
[
index
]
==
null
;
currentGroupByExprData
[
index
]
=
obj
;
return
;
}
index
=
exprToIndexInGroupByData
.
size
();
exprToIndexInGroupByData
.
put
(
expr
,
index
);
if
(
index
>=
currentGroupByExprData
.
length
)
{
currentGroupByExprData
=
Arrays
.
copyOf
(
currentGroupByExprData
,
currentGroupByExprData
.
length
*
2
);
// this can be null in lazy mode
if
(
currentGroupsKey
!=
null
)
{
// since we changed the size of the array, update the object in the groups map
groupByData
.
put
(
currentGroupsKey
,
currentGroupByExprData
);
}
}
currentGroupByExprData
[
index
]
=
obj
;
}
public
int
getCurrentGroupRowId
()
{
return
currentGroupRowId
;
}
}
@Override
@Override
...
@@ -411,38 +347,19 @@ public class Select extends Query {
...
@@ -411,38 +347,19 @@ public class Select extends Query {
}
}
private
void
queryGroup
(
int
columnCount
,
LocalResult
result
,
long
offset
,
boolean
quickOffset
)
{
private
void
queryGroup
(
int
columnCount
,
LocalResult
result
,
long
offset
,
boolean
quickOffset
)
{
groupByData
=
new
HashMap
<>();
if
(
groupData
==
null
)
{
currentGroupByExprData
=
null
;
groupData
=
new
SelectGroups
(
session
,
expressions
,
groupIndex
)
;
currentGroupsKey
=
null
;
}
exprToIndexInGroupByData
.
clear
();
groupData
.
reset
();
try
{
try
{
int
rowNumber
=
0
;
int
rowNumber
=
0
;
setCurrentRowNumber
(
0
);
setCurrentRowNumber
(
0
);
ValueArray
defaultGroup
=
ValueArray
.
get
(
new
Value
[
0
]);
int
sampleSize
=
getSampleSizeValue
(
session
);
int
sampleSize
=
getSampleSizeValue
(
session
);
while
(
topTableFilter
.
next
())
{
while
(
topTableFilter
.
next
())
{
setCurrentRowNumber
(
rowNumber
+
1
);
setCurrentRowNumber
(
rowNumber
+
1
);
if
(
isConditionMet
())
{
if
(
isConditionMet
())
{
rowNumber
++;
rowNumber
++;
if
(
groupIndex
==
null
)
{
groupData
.
nextSource
();
currentGroupsKey
=
defaultGroup
;
}
else
{
Value
[]
keyValues
=
new
Value
[
groupIndex
.
length
];
// update group
for
(
int
i
=
0
;
i
<
groupIndex
.
length
;
i
++)
{
int
idx
=
groupIndex
[
i
];
Expression
expr
=
expressions
.
get
(
idx
);
keyValues
[
i
]
=
expr
.
getValue
(
session
);
}
currentGroupsKey
=
ValueArray
.
get
(
keyValues
);
}
Object
[]
values
=
groupByData
.
get
(
currentGroupsKey
);
if
(
values
==
null
)
{
values
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())];
groupByData
.
put
(
currentGroupsKey
,
values
);
}
currentGroupByExprData
=
values
;
currentGroupRowId
++;
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
if
(
groupByExpression
==
null
||
!
groupByExpression
[
i
])
{
if
(
groupByExpression
==
null
||
!
groupByExpression
[
i
])
{
Expression
expr
=
expressions
.
get
(
i
);
Expression
expr
=
expressions
.
get
(
i
);
...
@@ -454,13 +371,8 @@ public class Select extends Query {
...
@@ -454,13 +371,8 @@ public class Select extends Query {
}
}
}
}
}
}
if
(
groupIndex
==
null
&&
groupByData
.
size
()
==
0
)
{
groupData
.
done
();
groupByData
.
put
(
defaultGroup
,
for
(
ValueArray
currentGroupsKey
;
(
currentGroupsKey
=
groupData
.
next
())
!=
null
;)
{
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())]);
}
for
(
Map
.
Entry
<
Value
,
Object
[]>
entry
:
groupByData
.
entrySet
())
{
currentGroupsKey
=
(
ValueArray
)
entry
.
getKey
();
currentGroupByExprData
=
entry
.
getValue
();
Value
[]
keyValues
=
currentGroupsKey
.
getList
();
Value
[]
keyValues
=
currentGroupsKey
.
getList
();
Value
[]
row
=
new
Value
[
columnCount
];
Value
[]
row
=
new
Value
[
columnCount
];
for
(
int
j
=
0
;
groupIndex
!=
null
&&
j
<
groupIndex
.
length
;
j
++)
{
for
(
int
j
=
0
;
groupIndex
!=
null
&&
j
<
groupIndex
.
length
;
j
++)
{
...
@@ -484,10 +396,7 @@ public class Select extends Query {
...
@@ -484,10 +396,7 @@ public class Select extends Query {
result
.
addRow
(
row
);
result
.
addRow
(
row
);
}
}
}
finally
{
}
finally
{
groupByData
=
null
;
groupData
.
reset
();
currentGroupsKey
=
null
;
currentGroupByExprData
=
null
;
exprToIndexInGroupByData
.
clear
();
}
}
}
}
...
@@ -1676,19 +1585,23 @@ public class Select extends Query {
...
@@ -1676,19 +1585,23 @@ public class Select extends Query {
*/
*/
private
final
class
LazyResultGroupSorted
extends
LazyResultSelect
{
private
final
class
LazyResultGroupSorted
extends
LazyResultSelect
{
Value
[]
previousKeyValues
;
private
Value
[]
previousKeyValues
;
LazyResultGroupSorted
(
Expression
[]
expressions
,
int
columnCount
)
{
LazyResultGroupSorted
(
Expression
[]
expressions
,
int
columnCount
)
{
super
(
expressions
,
columnCount
);
super
(
expressions
,
columnCount
);
currentGroupByExprData
=
null
;
if
(
groupData
==
null
)
{
currentGroupsKey
=
null
;
groupData
=
new
SelectGroups
(
getSession
(),
Select
.
this
.
expressions
,
groupIndex
);
}
else
{
// TODO is this branch possible?
groupData
.
resetLazy
();
}
}
}
@Override
@Override
public
void
reset
()
{
public
void
reset
()
{
super
.
reset
();
super
.
reset
();
currentGroupByExprData
=
null
;
groupData
.
resetLazy
()
;
currentGroupsKey
=
null
;
previousKeyValues
=
null
;
}
}
@Override
@Override
...
@@ -1708,15 +1621,13 @@ public class Select extends Query {
...
@@ -1708,15 +1621,13 @@ public class Select extends Query {
Value
[]
row
=
null
;
Value
[]
row
=
null
;
if
(
previousKeyValues
==
null
)
{
if
(
previousKeyValues
==
null
)
{
previousKeyValues
=
keyValues
;
previousKeyValues
=
keyValues
;
currentGroupByExprData
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
groupData
.
nextLazyGroup
();
expressions
.
size
())];
}
else
if
(!
Arrays
.
equals
(
previousKeyValues
,
keyValues
))
{
}
else
if
(!
Arrays
.
equals
(
previousKeyValues
,
keyValues
))
{
row
=
createGroupSortedRow
(
previousKeyValues
,
columnCount
);
row
=
createGroupSortedRow
(
previousKeyValues
,
columnCount
);
previousKeyValues
=
keyValues
;
previousKeyValues
=
keyValues
;
currentGroupByExprData
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
groupData
.
nextLazyGroup
();
expressions
.
size
())];
}
}
currentGroupRowId
++
;
groupData
.
nextLazyRow
()
;
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
if
(
groupByExpression
==
null
||
!
groupByExpression
[
i
])
{
if
(
groupByExpression
==
null
||
!
groupByExpression
[
i
])
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/dml/SelectGroups.java
0 → 100644
浏览文件 @
8323369e
/*
* 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
.
command
.
dml
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
/**
* Grouped data for aggregates.
*
* <p>
* Call sequence:
* </p>
* <ul>
* <li>{@link #reset()} (not required before the first execution).</li>
* <li>For each source row {@link #nextSource()} should be invoked.</li>
* <li>{@link #done()}.</li>
* <li>{@link #next()} is invoked inside a loop until it returns null.</li>
* </ul>
* <p>
* Call sequence for lazy group sorted result:
* </p>
* <ul>
* <li>{@link #resetLazy()} (not required before the first execution).</li>
* <li>For each source group {@link #nextLazyGroup()} should be invoked.</li>
* <li>For each source row {@link #nextLazyRow()} should be invoked. Each group
* can have one or more rows.</li>
* </ul>
*/
public
final
class
SelectGroups
{
private
final
Session
session
;
private
final
ArrayList
<
Expression
>
expressions
;
private
final
int
[]
groupIndex
;
/**
* The array of current group-by expression data e.g. AggregateData.
*/
private
Object
[]
currentGroupByExprData
;
/**
* Maps an expression object to an index, to use in accessing the Object[]
* pointed to by groupByData.
*/
private
final
HashMap
<
Expression
,
Integer
>
exprToIndexInGroupByData
=
new
HashMap
<>();
/**
* Map of group-by key to group-by expression data e.g. AggregateData
*/
private
HashMap
<
ValueArray
,
Object
[]>
groupByData
;
/**
* Key into groupByData that produces currentGroupByExprData. Not used in
* lazy mode.
*/
private
ValueArray
currentGroupsKey
;
/**
* The id of the current group.
*/
private
int
currentGroupRowId
;
/**
* The key for the default group.
*/
// Can be static, but TestClearReferences complains about it
private
ValueArray
defaultGroup
=
ValueArray
.
get
(
new
Value
[
0
]);
/**
* Cursor for {@link #next()} method.
*/
private
Iterator
<
Entry
<
ValueArray
,
Object
[]>>
cursor
;
/**
* Creates new instance of grouped data.
*
* @param session
* the session
* @param expressions
* the expressions
* @param groupIndex
* the indexes of group expressions, or null
*/
public
SelectGroups
(
Session
session
,
ArrayList
<
Expression
>
expressions
,
int
[]
groupIndex
)
{
this
.
session
=
session
;
this
.
expressions
=
expressions
;
this
.
groupIndex
=
groupIndex
;
}
/**
* Is there currently a group-by active
*/
public
boolean
isCurrentGroup
()
{
return
currentGroupByExprData
!=
null
;
}
/**
* Get the group-by data for the current group and the passed in expression.
*/
public
Object
getCurrentGroupExprData
(
Expression
expr
)
{
Integer
index
=
exprToIndexInGroupByData
.
get
(
expr
);
if
(
index
==
null
)
{
return
null
;
}
return
currentGroupByExprData
[
index
];
}
/**
* Set the group-by data for the current group and the passed in expression.
*/
public
void
setCurrentGroupExprData
(
Expression
expr
,
Object
obj
)
{
Integer
index
=
exprToIndexInGroupByData
.
get
(
expr
);
if
(
index
!=
null
)
{
assert
currentGroupByExprData
[
index
]
==
null
;
currentGroupByExprData
[
index
]
=
obj
;
return
;
}
index
=
exprToIndexInGroupByData
.
size
();
exprToIndexInGroupByData
.
put
(
expr
,
index
);
if
(
index
>=
currentGroupByExprData
.
length
)
{
currentGroupByExprData
=
Arrays
.
copyOf
(
currentGroupByExprData
,
currentGroupByExprData
.
length
*
2
);
// this can be null in lazy mode
if
(
currentGroupsKey
!=
null
)
{
// since we changed the size of the array, update the object in
// the groups map
groupByData
.
put
(
currentGroupsKey
,
currentGroupByExprData
);
}
}
currentGroupByExprData
[
index
]
=
obj
;
}
/**
* Returns identity of the current row. Used by aggregates to check whether
* they already processed this row or not.
*
* @return identity of the current row
*/
public
int
getCurrentGroupRowId
()
{
return
currentGroupRowId
;
}
/**
* Resets this group data for reuse.
*/
public
void
reset
()
{
groupByData
=
new
HashMap
<>();
currentGroupByExprData
=
null
;
currentGroupsKey
=
null
;
exprToIndexInGroupByData
.
clear
();
cursor
=
null
;
}
/**
* Invoked for each source row to evaluate group key and setup all necessary
* data for aggregates.
*/
public
void
nextSource
()
{
if
(
groupIndex
==
null
)
{
currentGroupsKey
=
defaultGroup
;
}
else
{
Value
[]
keyValues
=
new
Value
[
groupIndex
.
length
];
// update group
for
(
int
i
=
0
;
i
<
groupIndex
.
length
;
i
++)
{
int
idx
=
groupIndex
[
i
];
Expression
expr
=
expressions
.
get
(
idx
);
keyValues
[
i
]
=
expr
.
getValue
(
session
);
}
currentGroupsKey
=
ValueArray
.
get
(
keyValues
);
}
Object
[]
values
=
groupByData
.
get
(
currentGroupsKey
);
if
(
values
==
null
)
{
values
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())];
groupByData
.
put
(
currentGroupsKey
,
values
);
}
currentGroupByExprData
=
values
;
currentGroupRowId
++;
}
/**
* Invoked after all source rows are evaluated.
*/
public
void
done
()
{
if
(
groupIndex
==
null
&&
groupByData
.
size
()
==
0
)
{
groupByData
.
put
(
defaultGroup
,
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())]);
}
cursor
=
groupByData
.
entrySet
().
iterator
();
}
/**
* Returns the key of the next group.
*
* @return the key of the next group, or null
*/
public
ValueArray
next
()
{
if
(
cursor
.
hasNext
())
{
Map
.
Entry
<
ValueArray
,
Object
[]>
entry
=
cursor
.
next
();
currentGroupByExprData
=
entry
.
getValue
();
return
entry
.
getKey
();
}
return
null
;
}
/**
* Resets this group data for reuse in lazy mode.
*/
public
void
resetLazy
()
{
currentGroupByExprData
=
null
;
currentGroupsKey
=
null
;
}
/**
* Moves group data to the next group in lazy mode.
*/
public
void
nextLazyGroup
()
{
currentGroupByExprData
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())];
}
/**
* Moves group data to the next row in lazy mode.
*/
public
void
nextLazyRow
()
{
currentGroupRowId
++;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/ExpressionColumn.java
浏览文件 @
8323369e
...
@@ -8,6 +8,7 @@ package org.h2.expression;
...
@@ -8,6 +8,7 @@ package org.h2.expression;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.Parser
;
import
org.h2.command.Parser
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
import
org.h2.command.dml.SelectListColumnResolver
;
import
org.h2.command.dml.SelectListColumnResolver
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
...
@@ -158,13 +159,14 @@ public class ExpressionColumn extends Expression {
...
@@ -158,13 +159,14 @@ public class ExpressionColumn extends Expression {
if
(
select
==
null
)
{
if
(
select
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
MUST_GROUP_BY_COLUMN_1
,
getSQL
());
throw
DbException
.
get
(
ErrorCode
.
MUST_GROUP_BY_COLUMN_1
,
getSQL
());
}
}
if
(!
select
.
isCurrentGroup
())
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
();
if
(
groupData
==
null
)
{
// this is a different level (the enclosing query)
// this is a different level (the enclosing query)
return
;
return
;
}
}
Value
v
=
(
Value
)
select
.
getCurrentGroupExprData
(
this
);
Value
v
=
(
Value
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
v
==
null
)
{
if
(
v
==
null
)
{
select
.
setCurrentGroupExprData
(
this
,
now
);
groupData
.
setCurrentGroupExprData
(
this
,
now
);
}
else
{
}
else
{
if
(!
database
.
areEqual
(
now
,
v
))
{
if
(!
database
.
areEqual
(
now
,
v
))
{
throw
DbException
.
get
(
ErrorCode
.
MUST_GROUP_BY_COLUMN_1
,
getSQL
());
throw
DbException
.
get
(
ErrorCode
.
MUST_GROUP_BY_COLUMN_1
,
getSQL
());
...
@@ -176,8 +178,9 @@ public class ExpressionColumn extends Expression {
...
@@ -176,8 +178,9 @@ public class ExpressionColumn extends Expression {
public
Value
getValue
(
Session
session
)
{
public
Value
getValue
(
Session
session
)
{
Select
select
=
columnResolver
.
getSelect
();
Select
select
=
columnResolver
.
getSelect
();
if
(
select
!=
null
)
{
if
(
select
!=
null
)
{
if
(
select
.
isCurrentGroup
())
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
();
Value
v
=
(
Value
)
select
.
getCurrentGroupExprData
(
this
);
if
(
groupData
!=
null
)
{
Value
v
=
(
Value
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
v
!=
null
)
{
if
(
v
!=
null
)
{
return
v
;
return
v
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/Aggregate.java
浏览文件 @
8323369e
...
@@ -11,6 +11,7 @@ import java.util.Comparator;
...
@@ -11,6 +11,7 @@ import java.util.Comparator;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
...
@@ -295,12 +296,13 @@ public class Aggregate extends Expression {
...
@@ -295,12 +296,13 @@ public class Aggregate extends Expression {
// if (on != null) {
// if (on != null) {
// on.updateAggregate();
// on.updateAggregate();
// }
// }
if
(!
select
.
isCurrentGroup
())
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
();
if
(
groupData
==
null
)
{
// this is a different level (the enclosing query)
// this is a different level (the enclosing query)
return
;
return
;
}
}
int
groupRowId
=
select
.
getCurrentGroupRowId
();
int
groupRowId
=
groupData
.
getCurrentGroupRowId
();
if
(
lastGroupRowId
==
groupRowId
)
{
if
(
lastGroupRowId
==
groupRowId
)
{
// already visited
// already visited
return
;
return
;
...
@@ -312,10 +314,10 @@ public class Aggregate extends Expression {
...
@@ -312,10 +314,10 @@ public class Aggregate extends Expression {
return
;
return
;
}
}
}
}
AggregateData
data
=
(
AggregateData
)
select
.
getCurrentGroupExprData
(
this
);
AggregateData
data
=
(
AggregateData
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
data
==
null
)
{
if
(
data
==
null
)
{
data
=
AggregateData
.
create
(
type
);
data
=
AggregateData
.
create
(
type
);
select
.
setCurrentGroupExprData
(
this
,
data
);
groupData
.
setCurrentGroupExprData
(
this
,
data
);
}
}
Value
v
=
on
==
null
?
null
:
on
.
getValue
(
session
);
Value
v
=
on
==
null
?
null
:
on
.
getValue
(
session
);
if
(
type
==
AggregateType
.
GROUP_CONCAT
)
{
if
(
type
==
AggregateType
.
GROUP_CONCAT
)
{
...
@@ -378,13 +380,14 @@ public class Aggregate extends Expression {
...
@@ -378,13 +380,14 @@ public class Aggregate extends Expression {
DbException
.
throwInternalError
(
"type="
+
type
);
DbException
.
throwInternalError
(
"type="
+
type
);
}
}
}
}
if
(!
select
.
isCurrentGroup
())
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
();
if
(
groupData
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
}
}
AggregateData
data
=
(
AggregateData
)
select
.
getCurrentGroupExprData
(
this
);
AggregateData
data
=
(
AggregateData
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
data
==
null
)
{
if
(
data
==
null
)
{
data
=
AggregateData
.
create
(
type
);
data
=
AggregateData
.
create
(
type
);
select
.
setCurrentGroupExprData
(
this
,
data
);
groupData
.
setCurrentGroupExprData
(
this
,
data
);
}
}
switch
(
type
)
{
switch
(
type
)
{
case
GROUP_CONCAT:
{
case
GROUP_CONCAT:
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
浏览文件 @
8323369e
...
@@ -11,6 +11,7 @@ import org.h2.api.Aggregate;
...
@@ -11,6 +11,7 @@ import org.h2.api.Aggregate;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.Parser
;
import
org.h2.command.Parser
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.engine.UserAggregate
;
import
org.h2.engine.UserAggregate
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
...
@@ -168,14 +169,15 @@ public class JavaAggregate extends Expression {
...
@@ -168,14 +169,15 @@ public class JavaAggregate extends Expression {
@Override
@Override
public
Value
getValue
(
Session
session
)
{
public
Value
getValue
(
Session
session
)
{
if
(!
select
.
isCurrentGroup
())
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
();
if
(
groupData
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
}
}
try
{
try
{
Aggregate
agg
;
Aggregate
agg
;
if
(
distinct
)
{
if
(
distinct
)
{
agg
=
getInstance
();
agg
=
getInstance
();
AggregateDataCollecting
data
=
(
AggregateDataCollecting
)
select
.
getCurrentGroupExprData
(
this
);
AggregateDataCollecting
data
=
(
AggregateDataCollecting
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
data
!=
null
)
{
if
(
data
!=
null
)
{
for
(
Value
value
:
data
.
values
)
{
for
(
Value
value
:
data
.
values
)
{
if
(
args
.
length
==
1
)
{
if
(
args
.
length
==
1
)
{
...
@@ -191,7 +193,7 @@ public class JavaAggregate extends Expression {
...
@@ -191,7 +193,7 @@ public class JavaAggregate extends Expression {
}
}
}
}
}
else
{
}
else
{
agg
=
(
Aggregate
)
select
.
getCurrentGroupExprData
(
this
);
agg
=
(
Aggregate
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
agg
==
null
)
{
if
(
agg
==
null
)
{
agg
=
getInstance
();
agg
=
getInstance
();
}
}
...
@@ -208,12 +210,13 @@ public class JavaAggregate extends Expression {
...
@@ -208,12 +210,13 @@ public class JavaAggregate extends Expression {
@Override
@Override
public
void
updateAggregate
(
Session
session
)
{
public
void
updateAggregate
(
Session
session
)
{
if
(!
select
.
isCurrentGroup
())
{
SelectGroups
groupData
=
select
.
getGroupDataIfCurrent
();
if
(
groupData
==
null
)
{
// this is a different level (the enclosing query)
// this is a different level (the enclosing query)
return
;
return
;
}
}
int
groupRowId
=
select
.
getCurrentGroupRowId
();
int
groupRowId
=
groupData
.
getCurrentGroupRowId
();
if
(
lastGroupRowId
==
groupRowId
)
{
if
(
lastGroupRowId
==
groupRowId
)
{
// already visited
// already visited
return
;
return
;
...
@@ -228,10 +231,10 @@ public class JavaAggregate extends Expression {
...
@@ -228,10 +231,10 @@ public class JavaAggregate extends Expression {
try
{
try
{
if
(
distinct
)
{
if
(
distinct
)
{
AggregateDataCollecting
data
=
(
AggregateDataCollecting
)
select
.
getCurrentGroupExprData
(
this
);
AggregateDataCollecting
data
=
(
AggregateDataCollecting
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
data
==
null
)
{
if
(
data
==
null
)
{
data
=
new
AggregateDataCollecting
();
data
=
new
AggregateDataCollecting
();
select
.
setCurrentGroupExprData
(
this
,
data
);
groupData
.
setCurrentGroupExprData
(
this
,
data
);
}
}
Value
[]
argValues
=
new
Value
[
args
.
length
];
Value
[]
argValues
=
new
Value
[
args
.
length
];
Value
arg
=
null
;
Value
arg
=
null
;
...
@@ -242,10 +245,10 @@ public class JavaAggregate extends Expression {
...
@@ -242,10 +245,10 @@ public class JavaAggregate extends Expression {
}
}
data
.
add
(
session
.
getDatabase
(),
dataType
,
true
,
args
.
length
==
1
?
arg
:
ValueArray
.
get
(
argValues
));
data
.
add
(
session
.
getDatabase
(),
dataType
,
true
,
args
.
length
==
1
?
arg
:
ValueArray
.
get
(
argValues
));
}
else
{
}
else
{
Aggregate
agg
=
(
Aggregate
)
select
.
getCurrentGroupExprData
(
this
);
Aggregate
agg
=
(
Aggregate
)
groupData
.
getCurrentGroupExprData
(
this
);
if
(
agg
==
null
)
{
if
(
agg
==
null
)
{
agg
=
getInstance
();
agg
=
getInstance
();
select
.
setCurrentGroupExprData
(
this
,
agg
);
groupData
.
setCurrentGroupExprData
(
this
,
agg
);
}
}
Object
[]
argValues
=
new
Object
[
args
.
length
];
Object
[]
argValues
=
new
Object
[
args
.
length
];
Object
arg
=
null
;
Object
arg
=
null
;
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论