Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
d0c4469a
Unverified
提交
d0c4469a
authored
8月 28, 2018
作者:
Evgenij Ryazanov
提交者:
GitHub
8月 28, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1408 from katzyn/aggregate
Add MODE() aggregate function
上级
908705e8
c99b31fe
隐藏空白字符变更
内嵌
并排
正在显示
31 个修改的文件
包含
367 行增加
和
86 行删除
+367
-86
help.csv
h2/src/docsrc/help/help.csv
+21
-0
changelog.html
h2/src/docsrc/html/changelog.html
+8
-0
ErrorCode.java
h2/src/main/org/h2/api/ErrorCode.java
+12
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+64
-30
Aggregate.java
h2/src/main/org/h2/expression/aggregate/Aggregate.java
+31
-5
AggregateData.java
h2/src/main/org/h2/expression/aggregate/AggregateData.java
+4
-2
AggregateDataCollecting.java
.../org/h2/expression/aggregate/AggregateDataCollecting.java
+1
-1
AggregateDataCount.java
.../main/org/h2/expression/aggregate/AggregateDataCount.java
+1
-1
AggregateDataCountAll.java
...in/org/h2/expression/aggregate/AggregateDataCountAll.java
+1
-1
AggregateDataDefault.java
...ain/org/h2/expression/aggregate/AggregateDataDefault.java
+2
-2
AggregateDataHistogram.java
...n/org/h2/expression/aggregate/AggregateDataHistogram.java
+16
-29
AggregateDataMedian.java
...main/org/h2/expression/aggregate/AggregateDataMedian.java
+3
-1
AggregateDataMode.java
...c/main/org/h2/expression/aggregate/AggregateDataMode.java
+80
-0
AggregateDataSelectivity.java
...org/h2/expression/aggregate/AggregateDataSelectivity.java
+1
-1
JavaAggregate.java
h2/src/main/org/h2/expression/aggregate/JavaAggregate.java
+3
-1
LongDataCounter.java
h2/src/main/org/h2/expression/aggregate/LongDataCounter.java
+18
-0
package.html
h2/src/main/org/h2/expression/aggregate/package.html
+14
-0
DbException.java
h2/src/main/org/h2/message/DbException.java
+16
-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
TestScript.java
h2/src/test/org/h2/test/scripts/TestScript.java
+1
-1
mode.sql
h2/src/test/org/h2/test/scripts/functions/aggregate/mode.sql
+59
-0
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
d0c4469a
...
...
@@ -3416,6 +3416,27 @@ Aggregates are only allowed in select statements.
MEDIAN(X)
"
"Functions (Aggregate)","MODE","
{ MODE( value ) [ ORDER BY expression [ ASC | DESC ] ] }
| { MODE() WITHIN GROUP(ORDER BY expression [ ASC | DESC ]) }
[ FILTER ( WHERE expression ) ]
","
Returns the value that occurs with the greatest frequency.
If there are multiple values with the same frequency only one value will be returned.
In this situation value will be chosen based on optional ORDER BY clause
that should specify exactly the same expression as argument of this function.
Use ascending order to get smallest value or descending order to get largest value
from multiple values with the same frequency.
If this clause is not specified the exact chosen value is not determined in this situation.
NULL values are ignored in the calculation.
If no rows are selected, the result is NULL.
Aggregates are only allowed in select statements.
","
MODE(X)
MODE(X ORDER BY X)
MODE() WITHIN GROUP(ORDER BY X)
"
"Functions (Numeric)","ABS","
ABS ( { numeric } )
","
...
...
h2/src/docsrc/html/changelog.html
浏览文件 @
d0c4469a
...
...
@@ -21,6 +21,14 @@ Change Log
<h2>
Next Version (unreleased)
</h2>
<ul>
<li>
Issue #1407: Add a MODE() aggregate function
</li>
<li>
PR #1402: Duplicate conditions in column check constraint
</li>
<li>
PR #1399: Add more subclasses of SQLException and use it for some error codes
</li>
<li>
PR #1397: Add DATEADD return type detection
</li>
<li>
Issue #1393: Add INFORMATION_SCHEMA.COLUMNS.IS_VISIBLE
</li>
<li>
PR #1392: Some refactoring and assorted minor optimizations
...
...
h2/src/main/org/h2/api/ErrorCode.java
浏览文件 @
d0c4469a
...
...
@@ -402,6 +402,17 @@ public class ErrorCode {
*/
public
static
final
int
COLUMN_NOT_FOUND_1
=
42122
;
/**
* The error with code <code>42123</code> is thrown when
* identical expressions should be used, but different
* exceptions were found.
* Example:
* <pre>
* SELECT MODE(A ORDER BY B) FROM TEST;
* </pre>
*/
public
static
final
int
IDENTICAL_EXPRESSIONS_SHOULD_BE_USED
=
42131
;
// 0A: feature not supported
// HZ: remote database access
...
...
@@ -2068,6 +2079,7 @@ public class ErrorCode {
case
INDEX_NOT_FOUND_1:
return
"42S12"
;
case
DUPLICATE_COLUMN_NAME_1:
return
"42S21"
;
case
COLUMN_NOT_FOUND_1:
return
"42S22"
;
case
IDENTICAL_EXPRESSIONS_SHOULD_BE_USED:
return
"42S31"
;
// 0A: feature not supported
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
d0c4469a
...
...
@@ -145,8 +145,6 @@ import org.h2.engine.SysProperties;
import
org.h2.engine.User
;
import
org.h2.engine.UserAggregate
;
import
org.h2.engine.UserDataType
;
import
org.h2.expression.Aggregate
;
import
org.h2.expression.Aggregate.AggregateType
;
import
org.h2.expression.Alias
;
import
org.h2.expression.BinaryOperation
;
import
org.h2.expression.BinaryOperation.OpType
;
...
...
@@ -163,7 +161,6 @@ import org.h2.expression.ExpressionColumn;
import
org.h2.expression.ExpressionList
;
import
org.h2.expression.Function
;
import
org.h2.expression.FunctionCall
;
import
org.h2.expression.JavaAggregate
;
import
org.h2.expression.JavaFunction
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.Rownum
;
...
...
@@ -174,6 +171,9 @@ import org.h2.expression.UnaryOperation;
import
org.h2.expression.ValueExpression
;
import
org.h2.expression.Variable
;
import
org.h2.expression.Wildcard
;
import
org.h2.expression.aggregate.Aggregate
;
import
org.h2.expression.aggregate.Aggregate.AggregateType
;
import
org.h2.expression.aggregate.JavaAggregate
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.result.SortOrder
;
...
...
@@ -1209,12 +1209,7 @@ public class Parser {
}
private
int
parseSortType
()
{
int
sortType
=
0
;
if
(
readIf
(
"ASC"
))
{
// ignore
}
else
if
(
readIf
(
"DESC"
))
{
sortType
=
SortOrder
.
DESCENDING
;
}
int
sortType
=
parseSimpleSortType
();
if
(
readIf
(
"NULLS"
))
{
if
(
readIf
(
"FIRST"
))
{
sortType
|=
SortOrder
.
NULLS_FIRST
;
...
...
@@ -1226,6 +1221,13 @@ public class Parser {
return
sortType
;
}
private
int
parseSimpleSortType
()
{
if
(!
readIf
(
"ASC"
)
&&
readIf
(
"DESC"
))
{
return
SortOrder
.
DESCENDING
;
}
return
SortOrder
.
ASCENDING
;
}
private
String
[]
parseColumnList
()
{
ArrayList
<
String
>
columns
=
Utils
.
newSmallArrayList
();
do
{
...
...
@@ -2916,40 +2918,35 @@ public class Parser {
}
currentSelect
.
setGroupQuery
();
Aggregate
r
;
if
(
aggregateType
==
AggregateType
.
COUNT
)
{
switch
(
aggregateType
)
{
case
COUNT:
if
(
readIf
(
ASTERISK
))
{
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
null
,
currentSelect
,
false
);
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
null
,
currentSelect
,
false
);
}
else
{
boolean
distinct
=
readIf
(
DISTINCT
);
Expression
on
=
readExpression
();
if
(
on
instanceof
Wildcard
&&
!
distinct
)
{
// PostgreSQL compatibility: count(t.*)
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
null
,
currentSelect
,
false
);
r
=
new
Aggregate
(
AggregateType
.
COUNT_ALL
,
null
,
currentSelect
,
false
);
}
else
{
r
=
new
Aggregate
(
AggregateType
.
COUNT
,
on
,
currentSelect
,
distinct
);
r
=
new
Aggregate
(
AggregateType
.
COUNT
,
on
,
currentSelect
,
distinct
);
}
}
}
else
if
(
aggregateType
==
AggregateType
.
GROUP_CONCAT
)
{
break
;
case
GROUP_CONCAT:
{
boolean
distinct
=
readIf
(
DISTINCT
);
if
(
equalsToken
(
"GROUP_CONCAT"
,
aggregateName
))
{
r
=
new
Aggregate
(
AggregateType
.
GROUP_CONCAT
,
readExpression
(),
currentSelect
,
distinct
);
r
=
new
Aggregate
(
AggregateType
.
GROUP_CONCAT
,
readExpression
(),
currentSelect
,
distinct
);
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
r
.
setOrderByList
(
parseSimpleOrderList
());
}
if
(
readIf
(
"SEPARATOR"
))
{
r
.
setGroupConcatSeparator
(
readExpression
());
}
}
else
if
(
equalsToken
(
"STRING_AGG"
,
aggregateName
))
{
// PostgreSQL compatibility: string_agg(expression, delimiter)
r
=
new
Aggregate
(
AggregateType
.
GROUP_CONCAT
,
readExpression
(),
currentSelect
,
distinct
);
r
=
new
Aggregate
(
AggregateType
.
GROUP_CONCAT
,
readExpression
(),
currentSelect
,
distinct
);
read
(
COMMA
);
r
.
setGroupConcatSeparator
(
readExpression
());
if
(
readIf
(
ORDER
))
{
...
...
@@ -2959,19 +2956,47 @@ public class Parser {
}
else
{
r
=
null
;
}
}
else
if
(
aggregateType
==
AggregateType
.
ARRAY_AGG
)
{
break
;
}
case
ARRAY_AGG:
{
boolean
distinct
=
readIf
(
DISTINCT
);
r
=
new
Aggregate
(
AggregateType
.
ARRAY_AGG
,
readExpression
(),
currentSelect
,
distinct
);
r
=
new
Aggregate
(
AggregateType
.
ARRAY_AGG
,
readExpression
(),
currentSelect
,
distinct
);
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
r
.
setOrderByList
(
parseSimpleOrderList
());
}
}
else
{
break
;
}
case
MODE:
{
if
(
readIf
(
CLOSE_PAREN
))
{
read
(
"WITHIN"
);
read
(
GROUP
);
read
(
OPEN_PAREN
);
read
(
ORDER
);
read
(
"BY"
);
Expression
expr
=
readExpression
();
r
=
new
Aggregate
(
AggregateType
.
MODE
,
expr
,
currentSelect
,
false
);
setModeAggOrder
(
r
,
expr
);
}
else
{
Expression
expr
=
readExpression
();
r
=
new
Aggregate
(
aggregateType
,
expr
,
currentSelect
,
false
);
if
(
readIf
(
ORDER
))
{
read
(
"BY"
);
Expression
expr2
=
readExpression
();
String
sql
=
expr
.
getSQL
(),
sql2
=
expr2
.
getSQL
();
if
(!
sql
.
equals
(
sql2
))
{
throw
DbException
.
getSyntaxError
(
ErrorCode
.
IDENTICAL_EXPRESSIONS_SHOULD_BE_USED
,
sqlCommand
,
lastParseIndex
,
sql
,
sql2
);
}
setModeAggOrder
(
r
,
expr
);
}
}
break
;
}
default
:
boolean
distinct
=
readIf
(
DISTINCT
);
r
=
new
Aggregate
(
aggregateType
,
readExpression
(),
currentSelect
,
distinct
)
;
r
=
new
Aggregate
(
aggregateType
,
readExpression
(),
currentSelect
,
distinct
);
break
;
}
read
(
CLOSE_PAREN
);
if
(
r
!=
null
)
{
...
...
@@ -2980,6 +3005,15 @@ public class Parser {
return
r
;
}
private
void
setModeAggOrder
(
Aggregate
r
,
Expression
expr
)
{
ArrayList
<
SelectOrderBy
>
orderList
=
new
ArrayList
<>(
1
);
SelectOrderBy
order
=
new
SelectOrderBy
();
order
.
expression
=
expr
;
order
.
sortType
=
parseSimpleSortType
();
orderList
.
add
(
order
);
r
.
setOrderByList
(
orderList
);
}
private
ArrayList
<
SelectOrderBy
>
parseSimpleOrderList
()
{
ArrayList
<
SelectOrderBy
>
orderList
=
Utils
.
newSmallArrayList
();
do
{
...
...
h2/src/main/org/h2/expression/Aggregate.java
→
h2/src/main/org/h2/expression/
aggregate/
Aggregate.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
...
...
@@ -13,6 +13,9 @@ import org.h2.api.ErrorCode;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
...
...
@@ -129,10 +132,16 @@ public class Aggregate extends Expression {
* The aggregate type for MEDIAN(expression).
*/
MEDIAN
,
/**
* The aggregate type for ARRAY_AGG(expression).
*/
ARRAY_AGG
ARRAY_AGG
,
/**
* The aggregate type for MODE(expression).
*/
MODE
,
}
private
static
final
HashMap
<
String
,
AggregateType
>
AGGREGATES
=
new
HashMap
<>(
64
);
...
...
@@ -200,6 +209,9 @@ public class Aggregate extends Expression {
addAggregate
(
"BIT_AND"
,
AggregateType
.
BIT_AND
);
addAggregate
(
"MEDIAN"
,
AggregateType
.
MEDIAN
);
addAggregate
(
"ARRAY_AGG"
,
AggregateType
.
ARRAY_AGG
);
addAggregate
(
"MODE"
,
AggregateType
.
MODE
);
// Oracle compatibility
addAggregate
(
"STATS_MODE"
,
AggregateType
.
MODE
);
}
private
static
void
addAggregate
(
String
name
,
AggregateType
type
)
{
...
...
@@ -372,7 +384,8 @@ public class Aggregate extends Expression {
data
=
AggregateData
.
create
(
type
);
select
.
setCurrentGroupExprData
(
this
,
data
);
}
if
(
type
==
AggregateType
.
GROUP_CONCAT
)
{
switch
(
type
)
{
case
GROUP_CONCAT:
{
Value
[]
array
=
((
AggregateDataCollecting
)
data
).
getArray
();
if
(
array
==
null
)
{
return
ValueNull
.
INSTANCE
;
...
...
@@ -399,7 +412,8 @@ public class Aggregate extends Expression {
buff
.
append
(
s
);
}
return
ValueString
.
get
(
buff
.
toString
());
}
else
if
(
type
==
AggregateType
.
ARRAY_AGG
)
{
}
case
ARRAY_AGG:
{
Value
[]
array
=
((
AggregateDataCollecting
)
data
).
getArray
();
if
(
array
==
null
)
{
return
ValueNull
.
INSTANCE
;
...
...
@@ -414,7 +428,15 @@ public class Aggregate extends Expression {
}
return
ValueArray
.
get
(
array
);
}
return
data
.
getValue
(
session
.
getDatabase
(),
dataType
,
distinct
);
case
MODE:
if
(
orderByList
!=
null
)
{
return
((
AggregateDataMode
)
data
).
getOrderedValue
(
session
.
getDatabase
(),
dataType
,
(
orderByList
.
get
(
0
).
sortType
&
SortOrder
.
DESCENDING
)
!=
0
);
}
//$FALL-THROUGH$
default
:
return
data
.
getValue
(
session
.
getDatabase
(),
dataType
,
distinct
);
}
}
@Override
...
...
@@ -503,6 +525,7 @@ public class Aggregate extends Expression {
case
MIN:
case
MAX:
case
MEDIAN:
case
MODE:
break
;
case
STDDEV_POP:
case
STDDEV_SAMP:
...
...
@@ -673,6 +696,9 @@ public class Aggregate extends Expression {
break
;
case
ARRAY_AGG:
return
getSQLArrayAggregate
();
case
MODE:
text
=
"MODE"
;
break
;
default
:
throw
DbException
.
throwInternalError
(
"type="
+
type
);
}
...
...
h2/src/main/org/h2/expression/AggregateData.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateData.java
浏览文件 @
d0c4469a
...
...
@@ -3,10 +3,10 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.engine.Database
;
import
org.h2.expression.Aggregate.AggregateType
;
import
org.h2.expression.
aggregate.
Aggregate.AggregateType
;
import
org.h2.value.Value
;
/**
...
...
@@ -35,6 +35,8 @@ abstract class AggregateData {
return
new
AggregateDataHistogram
();
case
MEDIAN:
return
new
AggregateDataMedian
();
case
MODE:
return
new
AggregateDataMode
();
default
:
return
new
AggregateDataDefault
(
aggregateType
);
}
...
...
h2/src/main/org/h2/expression/AggregateDataCollecting.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataCollecting.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
java.util.ArrayList
;
import
java.util.Collection
;
...
...
h2/src/main/org/h2/expression/AggregateDataCount.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataCount.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.engine.Database
;
import
org.h2.util.ValueHashMap
;
...
...
h2/src/main/org/h2/expression/AggregateDataCountAll.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataCountAll.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.engine.Database
;
import
org.h2.message.DbException
;
...
...
h2/src/main/org/h2/expression/AggregateDataDefault.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataDefault.java
浏览文件 @
d0c4469a
...
...
@@ -3,10 +3,10 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.engine.Database
;
import
org.h2.expression.Aggregate.AggregateType
;
import
org.h2.expression.
aggregate.
Aggregate.AggregateType
;
import
org.h2.message.DbException
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.DataType
;
...
...
h2/src/main/org/h2/expression/AggregateDataHistogram.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataHistogram.java
浏览文件 @
d0c4469a
...
...
@@ -3,11 +3,11 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
java.util.Arrays
;
import
java.util.Comparator
;
import
java.util.Map
;
import
java.util.Map
.Entry
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.Mode
;
...
...
@@ -21,37 +21,35 @@ import org.h2.value.ValueLong;
* Data stored while calculating a HISTOGRAM aggregate.
*/
class
AggregateDataHistogram
extends
AggregateData
{
private
long
count
;
private
ValueHashMap
<
AggregateDataHistogram
>
distinctValues
;
private
ValueHashMap
<
LongDataCounter
>
distinctValues
;
@Override
void
add
(
Database
database
,
int
dataType
,
boolean
distinct
,
Value
v
)
{
if
(
distinctValues
==
null
)
{
distinctValues
=
ValueHashMap
.
newInstance
();
}
AggregateDataHistogram
a
=
distinctValues
.
get
(
v
);
LongDataCounter
a
=
distinctValues
.
get
(
v
);
if
(
a
==
null
)
{
if
(
distinctValues
.
size
()
<
Constants
.
SELECTIVITY_DISTINCT_COUNT
)
{
a
=
new
AggregateDataHistogram
();
distinctValues
.
put
(
v
,
a
);
if
(
distinctValues
.
size
()
>=
Constants
.
SELECTIVITY_DISTINCT_COUNT
)
{
return
;
}
a
=
new
LongDataCounter
();
distinctValues
.
put
(
v
,
a
);
}
if
(
a
!=
null
)
{
a
.
count
++;
}
a
.
count
++;
}
@Override
Value
getValue
(
Database
database
,
int
dataType
,
boolean
distinct
)
{
if
(
distinct
)
{
count
=
0
;
groupDistinct
(
database
,
dataType
);
if
(
distinctValues
==
null
)
{
return
ValueArray
.
get
(
new
Value
[
0
]).
convertTo
(
dataType
);
}
ValueArray
[]
values
=
new
ValueArray
[
distinctValues
.
size
()];
int
i
=
0
;
for
(
Map
.
Entry
<
Value
,
AggregateDataHistogram
>
entry
:
distinctValues
.
entries
())
{
AggregateDataHistogram
d
=
entry
.
getValue
();
values
[
i
]
=
ValueArray
.
get
(
new
Value
[]
{
entry
.
getKey
(),
ValueLong
.
get
(
d
.
count
)
});
for
(
Entry
<
Value
,
LongDataCounter
>
entry
:
distinctValues
.
entries
())
{
LongDataCounter
d
=
entry
.
getValue
();
values
[
i
]
=
ValueArray
.
get
(
new
Value
[]
{
entry
.
getKey
(),
ValueLong
.
get
(
d
istinct
?
1L
:
d
.
count
)
});
i
++;
}
final
Mode
mode
=
database
.
getMode
();
...
...
@@ -64,18 +62,7 @@ class AggregateDataHistogram extends AggregateData {
return
a1
.
compareTo
(
a2
,
mode
,
compareMode
);
}
});
Value
v
=
ValueArray
.
get
(
values
);
return
v
.
convertTo
(
dataType
);
}
private
void
groupDistinct
(
Database
database
,
int
dataType
)
{
if
(
distinctValues
==
null
)
{
return
;
}
count
=
0
;
for
(
Value
v
:
distinctValues
.
keys
())
{
add
(
database
,
dataType
,
false
,
v
);
}
return
ValueArray
.
get
(
values
).
convertTo
(
dataType
);
}
}
h2/src/main/org/h2/expression/AggregateDataMedian.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataMedian.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
java.math.BigDecimal
;
import
java.util.ArrayList
;
...
...
@@ -14,6 +14,8 @@ import org.h2.engine.Database;
import
org.h2.engine.Mode
;
import
org.h2.engine.Session
;
import
org.h2.engine.SysProperties
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
import
org.h2.result.SearchRow
;
...
...
h2/src/main/org/h2/expression/aggregate/AggregateDataMode.java
0 → 100644
浏览文件 @
d0c4469a
/*
* 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
java.util.Map.Entry
;
import
org.h2.engine.Database
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
* Data stored while calculating a MODE aggregate.
*/
class
AggregateDataMode
extends
AggregateData
{
private
ValueHashMap
<
LongDataCounter
>
distinctValues
;
@Override
void
add
(
Database
database
,
int
dataType
,
boolean
distinct
,
Value
v
)
{
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
;
}
if
(
distinctValues
==
null
)
{
distinctValues
=
ValueHashMap
.
newInstance
();
}
LongDataCounter
a
=
distinctValues
.
get
(
v
);
if
(
a
==
null
)
{
a
=
new
LongDataCounter
();
distinctValues
.
put
(
v
,
a
);
}
a
.
count
++;
}
@Override
Value
getValue
(
Database
database
,
int
dataType
,
boolean
distinct
)
{
Value
v
=
ValueNull
.
INSTANCE
;
if
(
distinctValues
!=
null
)
{
long
count
=
0L
;
for
(
Entry
<
Value
,
LongDataCounter
>
entry
:
distinctValues
.
entries
())
{
long
c
=
entry
.
getValue
().
count
;
if
(
c
>
count
)
{
v
=
entry
.
getKey
();
count
=
c
;
}
}
}
return
v
.
convertTo
(
dataType
);
}
Value
getOrderedValue
(
Database
database
,
int
dataType
,
boolean
desc
)
{
Value
v
=
ValueNull
.
INSTANCE
;
if
(
distinctValues
!=
null
)
{
long
count
=
0L
;
for
(
Entry
<
Value
,
LongDataCounter
>
entry
:
distinctValues
.
entries
())
{
long
c
=
entry
.
getValue
().
count
;
if
(
c
>
count
)
{
v
=
entry
.
getKey
();
count
=
c
;
}
else
if
(
c
==
count
)
{
Value
v2
=
entry
.
getKey
();
int
cmp
=
database
.
compareTypeSafe
(
v
,
v2
);
if
(
desc
)
{
if
(
cmp
>=
0
)
{
continue
;
}
}
else
if
(
cmp
<=
0
)
{
continue
;
}
v
=
v2
;
}
}
}
return
v
.
convertTo
(
dataType
);
}
}
h2/src/main/org/h2/expression/AggregateDataSelectivity.java
→
h2/src/main/org/h2/expression/
aggregate/
AggregateDataSelectivity.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
...
...
h2/src/main/org/h2/expression/JavaAggregate.java
→
h2/src/main/org/h2/expression/
aggregate/
JavaAggregate.java
浏览文件 @
d0c4469a
...
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
expression
;
package
org
.
h2
.
expression
.
aggregate
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
...
...
@@ -13,6 +13,8 @@ import org.h2.command.Parser;
import
org.h2.command.dml.Select
;
import
org.h2.engine.Session
;
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
;
...
...
h2/src/main/org/h2/expression/aggregate/LongDataCounter.java
0 → 100644
浏览文件 @
d0c4469a
/*
* 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
;
/**
* Counter.
*/
final
class
LongDataCounter
{
/**
* The value.
*/
long
count
;
}
h2/src/main/org/h2/expression/aggregate/package.html
0 → 100644
浏览文件 @
d0c4469a
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0, Version 1.0,
and under the Eclipse Public License, Version 1.0
Initial Developer: H2 Group
-->
<html
xmlns=
"http://www.w3.org/1999/xhtml"
lang=
"en"
xml:lang=
"en"
>
<head><meta
http-equiv=
"Content-Type"
content=
"text/html;charset=utf-8"
/><title>
Javadoc package documentation
</title></head><body
style=
"font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"
><p>
Aggregate functions.
</p></body></html>
\ No newline at end of file
h2/src/main/org/h2/message/DbException.java
浏览文件 @
d0c4469a
...
...
@@ -237,6 +237,22 @@ public class DbException extends RuntimeException {
null
,
sql
,
message
));
}
/**
* Create a syntax error exception for a specific error code.
*
* @param errorCode the error code
* @param sql the SQL statement
* @param index the position of the error in the SQL statement
* @param params the list of parameters of the message
* @return the exception
*/
public
static
DbException
getSyntaxError
(
int
errorCode
,
String
sql
,
int
index
,
String
...
params
)
{
sql
=
StringUtils
.
addAsterisk
(
sql
,
index
);
String
sqlstate
=
ErrorCode
.
getState
(
errorCode
);
String
message
=
translate
(
sqlstate
,
params
);
return
new
DbException
(
getJdbcSQLException
(
message
,
sql
,
sqlstate
,
errorCode
,
null
,
null
));
}
/**
* Gets a SQL exception meaning this feature is not supported.
*
...
...
h2/src/main/org/h2/res/_messages_cs.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Index {0} nenalezen
42S21=Duplicitní název sloupce {0}
42S22=Sloupec {0} nenalezen
42S3
2=Nastavení {0} nenalezeno
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=Příkaz byl zrušen nebo připojení vypršelo
90000=Funkce {0} musí vracet výsledek
90001=Metoda neumožňuje dotazování. Použijte execute nebo executeQuery namísto executeUpdate
...
...
h2/src/main/org/h2/res/_messages_de.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Index {0} nicht gefunden
42S21=Doppelter Feldname {0}
42S22=Feld {0} nicht gefunden
42S3
2=Einstellung {0} nicht gefunden
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=Befehl wurde abgebrochen oder das Session-Timeout ist abgelaufen
90000=Funktion {0} muss Zeilen zurückgeben
90001=Methode nicht zulässig für eine Abfrage. Erlaubt sind execute oder executeQuery, nicht jedoch executeUpdate
...
...
h2/src/main/org/h2/res/_messages_en.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Index {0} not found
42S21=Duplicate column name {0}
42S22=Column {0} not found
42S3
2=Setting {0} not found
42S3
1=Identical expressions should be used; expected {0}, found {1}
57014=Statement was canceled or the session timed out
90000=Function {0} must return a result set
90001=Method is not allowed for a query. Use execute or executeQuery instead of executeUpdate
...
...
h2/src/main/org/h2/res/_messages_es.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Indice {0} no encontrado
42S21=Nombre de columna Duplicada {0}
42S22=Columna {0} no encontrada
42S3
2=Setting {0} no encontrado
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=Ls sentencia fue cancelado ó la sesión expiró por tiempo vencido
90000=Función {0} debe devolver un set de resultados (ResultSet)
90001=Metodo no permitido en un query. Use execute ó executeQuery en lugar de executeUpdate
...
...
h2/src/main/org/h2/res/_messages_fr.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Index {0} non trouvé
42S21=Duplication du nom de colonnes {0}
42S22=Colonne {0} non trouvée
42S3
2=Paramètre {0} non trouvé
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=L'instruction a été annulée ou la session a expiré
90000=La fonction {0} doit retourner résultat
90001=Methode non autorisée pour une requête. Utilisez execute ou executeQuery à la place d'executeUpdate
...
...
h2/src/main/org/h2/res/_messages_ja.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=インデックス {0} が見つかりません
42S21=列名 {0} が重複しています
42S22=列 {0} が見つかりません
42S3
2=設定 {0} が見つかりません
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=ステートメントがキャンセルされたか、セッションがタイムアウトしました
90000=関数 {0} はリザルトセットを返さなければなりません
90001=メソッドはクエリをサポートしていません。executeUpdateのかわりに、excute、またはexecuteQueryを使用してください
...
...
h2/src/main/org/h2/res/_messages_pl.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Indeks {0} nie istnieje
42S21=Zduplikowana nazwa kolumny {0}
42S22=Kolumna {0} nie istnieje
42S3
2=Ustawienie {0} nie istnieje
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=Kwerenda została anulowana albo sesja wygasła
90000=Funkcja {0} musi zwrócić dane
90001=Metoda nie jest dozwolona w kwerendzie
...
...
h2/src/main/org/h2/res/_messages_pt_br.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=índice {0} não foi encontrado
42S21=Nome duplicado da coluna {0}
42S22=Coluna {0} não foi encontrada
42S3
2=Definição {0} não foi encontrada
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=#Statement was canceled or the session timed out
90000=Função {0} deve retornar algum resultado
90001=O método não esta hábilitado para consulta. Use o execute ou o executeQuery em vez de executeUpdate
...
...
h2/src/main/org/h2/res/_messages_ru.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Индекс {0} не найден
42S21=Повтор имени столбца {0}
42S22=Столбец {0} не найден
42S3
2=Настройка {0} не найдена
42S3
1=Должны использоваться идентичные выражения; ожидалось {0}, получено {1}
57014=Запрос был отменен или закончилось время ожидания сессии
90000=Функция {0} должна возвращать набор записей
90001=Метод не разрешен для запросов. Используйте execute или executeQuery вместо executeUpdate
...
...
h2/src/main/org/h2/res/_messages_sk.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=Index {0} nenájdený
42S21=Duplicitné meno stĺpca {0}
42S22=Stĺpec {0} nenájdený
42S3
2=Nastavenie {0} nenájdené
42S3
1=#Identical expressions should be used; expected {0}, found {1}
57014=Príkaz bol zrušený alebo vypršal časový limit sedenia
90000=Funkcia {0} musí vracať výsledok (result set)
90001=Metóda nie je povolená pre dopyt (query). Použite execute alebo executeQuery namiesto executeUpdate
...
...
h2/src/main/org/h2/res/_messages_zh_cn.prop
浏览文件 @
d0c4469a
...
...
@@ -31,7 +31,7 @@
42S12=找不到索引 {0}
42S21=重复的字段: {0}
42S22=找不到字段 {0}
42S3
2=找不到设置 {0
}
42S3
1=#Identical expressions should be used; expected {0}, found {1
}
57014=语句已取消执行或会话已过期
90000={0} 函数必须返回一个结果集
90001=不允许在查询内使用的方法,使用execute 或 executeQuery 代替 executeUpdate
...
...
h2/src/test/org/h2/test/scripts/TestScript.java
浏览文件 @
d0c4469a
...
...
@@ -137,7 +137,7 @@ public class TestScript extends TestDb {
testScript
(
"other/"
+
s
+
".sql"
);
}
for
(
String
s
:
new
String
[]
{
"avg"
,
"bit-and"
,
"bit-or"
,
"count"
,
"group-concat"
,
"max"
,
"median"
,
"min"
,
"selectivity"
,
"stddev-pop"
,
"group-concat"
,
"max"
,
"median"
,
"min"
,
"
mode"
,
"
selectivity"
,
"stddev-pop"
,
"stddev-samp"
,
"sum"
,
"var-pop"
,
"var-samp"
,
"array-agg"
})
{
testScript
(
"functions/aggregate/"
+
s
+
".sql"
);
}
...
...
h2/src/test/org/h2/test/scripts/functions/aggregate/mode.sql
0 → 100644
浏览文件 @
d0c4469a
-- 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
(
V
INT
);
>
ok
SELECT
MODE
(
V
)
FROM
TEST
;
>>
null
SELECT
MODE
(
DISTINCT
V
)
FROM
TEST
;
>
exception
SYNTAX_ERROR_2
INSERT
INTO
TEST
VALUES
(
NULL
);
>
update
count
:
1
SELECT
MODE
(
V
)
FROM
TEST
;
>>
null
INSERT
INTO
TEST
VALUES
(
1
),
(
2
),
(
3
),
(
1
),
(
2
),
(
1
);
>
update
count
:
6
SELECT
MODE
(
V
),
MODE
(
V
)
FILTER
(
WHERE
(
V
>
1
)),
MODE
(
V
)
FILTER
(
WHERE
(
V
<
0
))
FROM
TEST
;
>
MODE
(
V
)
MODE
(
V
)
FILTER
(
WHERE
(
V
>
1
))
MODE
(
V
)
FILTER
(
WHERE
(
V
<
0
))
>
------- ------------------------------ ------------------------------
>
1
2
null
>
rows
:
1
-- Oracle compatibility
SELECT
STATS_MODE
(
V
)
FROM
TEST
;
>>
1
INSERT
INTO
TEST
VALUES
(
2
),
(
3
),
(
3
);
>
update
count
:
3
SELECT
MODE
(
V
ORDER
BY
V
)
FROM
TEST
;
>>
1
SELECT
MODE
(
V
ORDER
BY
V
ASC
)
FROM
TEST
;
>>
1
SELECT
MODE
(
V
ORDER
BY
V
DESC
)
FROM
TEST
;
>>
3
SELECT
MODE
(
V
ORDER
BY
V
+
1
)
FROM
TEST
;
>
exception
IDENTICAL_EXPRESSIONS_SHOULD_BE_USED
SELECT
MODE
()
WITHIN
GROUP
(
ORDER
BY
V
)
FROM
TEST
;
>>
1
SELECT
MODE
()
WITHIN
GROUP
(
ORDER
BY
V
ASC
)
FROM
TEST
;
>>
1
SELECT
MODE
()
WITHIN
GROUP
(
ORDER
BY
V
DESC
)
FROM
TEST
;
>>
3
DROP
TABLE
TEST
;
>
ok
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论