Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
8ca2feb0
提交
8ca2feb0
authored
7 年前
作者:
Owner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Issue#479 Intermediate save before refactor to remove heuristic
上级
f21ea8cd
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
125 行增加
和
21 行删除
+125
-21
help.csv
h2/src/docsrc/help/help.csv
+3
-3
Parser.java
h2/src/main/org/h2/command/Parser.java
+32
-3
RecursiveQueryHeuristic.java
h2/src/main/org/h2/command/dml/RecursiveQueryHeuristic.java
+2
-2
ViewIndex.java
h2/src/main/org/h2/index/ViewIndex.java
+3
-2
DbException.java
h2/src/main/org/h2/message/DbException.java
+2
-2
DbNotRecursiveException.java
h2/src/main/org/h2/message/DbNotRecursiveException.java
+28
-0
Column.java
h2/src/main/org/h2/table/Column.java
+0
-3
RangeTable.java
h2/src/main/org/h2/table/RangeTable.java
+2
-1
Table.java
h2/src/main/org/h2/table/Table.java
+17
-4
TableView.java
h2/src/main/org/h2/table/TableView.java
+34
-0
TestGeneralCommonTableQueries.java
...rc/test/org/h2/test/db/TestGeneralCommonTableQueries.java
+2
-1
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
8ca2feb0
...
...
@@ -199,10 +199,10 @@ WITH [ RECURSIVE ] { name [( columnName [,...] )]
","
Can be used to create a recursive query.
For recursive queries the first select has to be a UNION.
Non-recursive queries are also supported
,
One or more common table entries can be use referred to by name.
Non-recursive queries are also supported
.
One or more common table entries can be use referred to by name.
.
Column name declarations are now optional - the column names will be inferred from the named select queries.
Positional parameters are not currently
correctly
supported.
Positional parameters are not currently supported.
","
WITH RECURSIVE t(n) AS (
SELECT 1
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/Parser.java
浏览文件 @
8ca2feb0
...
...
@@ -76,7 +76,7 @@ import org.h2.command.dml.Insert;
import
org.h2.command.dml.Merge
;
import
org.h2.command.dml.NoOperation
;
import
org.h2.command.dml.Query
;
import
org.h2.command.dml.RecursiveQuery
;
import
org.h2.command.dml.RecursiveQuery
Heuristic
;
import
org.h2.command.dml.Replace
;
import
org.h2.command.dml.RunScriptCommand
;
import
org.h2.command.dml.ScriptCommand
;
...
...
@@ -126,6 +126,7 @@ import org.h2.expression.Variable;
import
org.h2.expression.Wildcard
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.message.DbNotRecursiveException
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
import
org.h2.schema.Sequence
;
...
...
@@ -4930,10 +4931,38 @@ public class Parser {
session
.
removeLocalTempTable
(
recursiveTable
);
}
int
id
=
database
.
allocateObjectId
();
boolean
isRecursive
=
RecursiveQuery
.
isRecursive
(
tempViewName
,
querySQL
);
TableView
view
=
new
TableView
(
schema
,
id
,
tempViewName
,
querySQL
,
boolean
isRecursive
=
true
;
//RecursiveQueryHeuristic.isRecursive(tempViewName,querySQL);
TableView
view
=
null
;
do
{
try
{
view
=
new
TableView
(
schema
,
id
,
tempViewName
,
querySQL
,
parameters
,
columnTemplateList
.
toArray
(
new
Column
[
0
]),
session
,
isRecursive
);
}
catch
(
DbNotRecursiveException
e
){
if
(
isRecursive
==
false
){
throw
e
;
}
isRecursive
=
false
;
view
=
null
;
System
.
out
.
println
(
"repeat new table by exeception"
);
continue
;
}
HashSet
<
DbObject
>
subDependencies
=
new
HashSet
<
DbObject
>();
view
.
addStrictSubDependencies
(
subDependencies
,
false
);
System
.
out
.
println
(
"tempViewName="
+
tempViewName
);
System
.
out
.
println
(
"subDependencies="
+
subDependencies
);
System
.
out
.
println
(
"isRecursiveQueryDetected="
+
view
.
isRecursiveQueryDetected
());
boolean
isRecursiveByDeepAnalysis
=
subDependencies
.
contains
(
recursiveTable
);
System
.
out
.
println
(
"isRecursiveByDeepAnalysis="
+
isRecursiveByDeepAnalysis
);
if
(
view
.
isRecursiveQueryDetected
()!=
isRecursive
){
isRecursive
=
view
.
isRecursiveQueryDetected
();
view
=
null
;
System
.
out
.
println
(
"repeat new table creation by view.isRecursiveQueryDetected()"
);
continue
;
}
}
while
(
view
==
null
);
view
.
setTableExpression
(
true
);
view
.
setTemporary
(
true
);
session
.
addLocalTempTable
(
view
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/dml/RecursiveQuery.java
→
h2/src/main/org/h2/command/dml/RecursiveQuery
Heuristic
.java
浏览文件 @
8ca2feb0
...
...
@@ -3,11 +3,11 @@ package org.h2.command.dml;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
public
class
RecursiveQuery
{
public
class
RecursiveQuery
Heuristic
{
// A query is recursive if it references it's own name in its definition
public
static
boolean
isRecursive
(
String
tempViewName
,
String
querySQL
)
{
boolean
foundAny
=
RecursiveQuery
.
foundAny
(
tempViewName
,
querySQL
);
boolean
foundAny
=
RecursiveQuery
Heuristic
.
foundAny
(
tempViewName
,
querySQL
);
//System.out.println("foundAny="+foundAny);
return
foundAny
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/ViewIndex.java
浏览文件 @
8ca2feb0
...
...
@@ -19,6 +19,7 @@ import org.h2.engine.Session;
import
org.h2.expression.Comparison
;
import
org.h2.expression.Parameter
;
import
org.h2.message.DbException
;
import
org.h2.message.DbNotRecursiveException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.Row
;
...
...
@@ -195,12 +196,12 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
query
.
setNeverLazy
(
true
);
}
if
(!
query
.
isUnion
())
{
throw
DbException
.
get
(
ErrorCode
.
SYNTAX_ERROR_2
,
throw
Db
NotRecursive
Exception
.
get
(
ErrorCode
.
SYNTAX_ERROR_2
,
"recursive queries without UNION ALL"
);
}
SelectUnion
union
=
(
SelectUnion
)
query
;
if
(
union
.
getUnionType
()
!=
SelectUnion
.
UNION_ALL
)
{
throw
DbException
.
get
(
ErrorCode
.
SYNTAX_ERROR_2
,
throw
Db
NotRecursive
Exception
.
get
(
ErrorCode
.
SYNTAX_ERROR_2
,
"recursive queries without UNION ALL"
);
}
Query
left
=
union
.
getLeft
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/message/DbException.java
浏览文件 @
8ca2feb0
...
...
@@ -70,11 +70,11 @@ public class DbException extends RuntimeException {
}
}
pr
ivate
DbException
(
SQLException
e
)
{
pr
otected
DbException
(
SQLException
e
)
{
super
(
e
.
getMessage
(),
e
);
}
pr
ivate
static
String
translate
(
String
key
,
String
...
params
)
{
pr
otected
static
String
translate
(
String
key
,
String
...
params
)
{
String
message
=
null
;
if
(
MESSAGES
!=
null
)
{
// Tomcat sets final static fields to null sometimes
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/message/DbNotRecursiveException.java
0 → 100755
浏览文件 @
8ca2feb0
package
org
.
h2
.
message
;
import
java.sql.SQLException
;
import
org.h2.api.ErrorCode
;
import
org.h2.jdbc.JdbcSQLException
;
public
class
DbNotRecursiveException
extends
DbException
{
private
static
final
long
serialVersionUID
=
-
5941745175474148318L
;
public
static
DbNotRecursiveException
get
(
int
errorCode
,
String
p1
)
{
return
get
(
errorCode
,
new
String
[]
{
p1
});
}
public
static
DbNotRecursiveException
get
(
int
errorCode
,
String
...
params
)
{
return
new
DbNotRecursiveException
(
getJdbcSQLException
(
errorCode
,
null
,
params
));
}
private
static
JdbcSQLException
getJdbcSQLException
(
int
errorCode
,
Throwable
cause
,
String
...
params
)
{
String
sqlstate
=
ErrorCode
.
getState
(
errorCode
);
String
message
=
translate
(
sqlstate
,
params
);
return
new
JdbcSQLException
(
message
,
null
,
sqlstate
,
errorCode
,
cause
,
null
);
}
private
DbNotRecursiveException
(
SQLException
e
)
{
super
(
e
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/Column.java
浏览文件 @
8ca2feb0
...
...
@@ -738,9 +738,6 @@ public class Column {
public
String
toString
()
{
return
name
;
}
public
String
toStringWithType
()
{
return
DataType
.
getTypeClassName
(
type
)+
":"
+
name
;
}
/**
* Check whether the new column is of the same type and not more restricted
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/RangeTable.java
浏览文件 @
8ca2feb0
...
...
@@ -144,7 +144,8 @@ public class RangeTable extends Table {
@Override
public
TableType
getTableType
()
{
throw
DbException
.
throwInternalError
(
toString
());
return
TableType
.
SYSTEM_TABLE
;
//throw DbException.throwInternalError(toString());
}
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/Table.java
浏览文件 @
8ca2feb0
...
...
@@ -352,12 +352,23 @@ public abstract class Table extends SchemaObjectBase {
}
/**
* Add all objects that this table depends on to the hash set.
* Add all objects that this table depends on to the hash set
, including this object
.
*
* @param dependencies the current set of dependencies
*/
public
void
addDependencies
(
HashSet
<
DbObject
>
dependencies
)
{
if
(
dependencies
.
contains
(
this
))
{
addStrictSubDependencies
(
dependencies
,
false
);
dependencies
.
add
(
this
);
}
/**
* Add all objects that this table depends on to the hash set, excluding
* this object (unless it is has recursive references).
*
* @param dependencies the current set of dependencies
*/
public
void
addStrictSubDependencies
(
HashSet
<
DbObject
>
dependencies
,
boolean
visitColumnTables
)
{
if
(
dependencies
.
contains
(
this
))
{
// avoid endless recursion
return
;
}
...
...
@@ -370,14 +381,16 @@ public abstract class Table extends SchemaObjectBase {
dependencies
);
for
(
Column
col
:
columns
)
{
col
.
isEverything
(
visitor
);
if
(
visitColumnTables
&&
col
.
getTable
()!=
null
){
dependencies
.
add
(
col
.
getTable
());
}
}
if
(
constraints
!=
null
)
{
for
(
Constraint
c
:
constraints
)
{
c
.
isEverything
(
visitor
);
}
}
dependencies
.
add
(
this
);
}
}
@Override
public
ArrayList
<
DbObject
>
getChildren
()
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/TableView.java
浏览文件 @
8ca2feb0
...
...
@@ -8,7 +8,9 @@ package org.h2.table;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.Prepared
;
import
org.h2.command.dml.Query
;
...
...
@@ -57,6 +59,7 @@ public class TableView extends Table {
private
Query
topQuery
;
private
ResultInterface
recursiveResult
;
private
boolean
tableExpression
;
private
boolean
isRecursiveQueryDetected
;
public
TableView
(
Schema
schema
,
int
id
,
String
name
,
String
querySQL
,
ArrayList
<
Parameter
>
params
,
Column
[]
columnTemplates
,
Session
session
,
...
...
@@ -94,6 +97,7 @@ public class TableView extends Table {
this
.
querySQL
=
querySQL
;
this
.
columnTemplates
=
columnTemplates
;
this
.
recursive
=
recursive
;
this
.
isRecursiveQueryDetected
=
false
;
index
=
new
ViewIndex
(
this
,
querySQL
,
params
,
recursive
);
initColumnsAndTables
(
session
);
}
...
...
@@ -206,6 +210,9 @@ public class TableView extends Table {
// if it can't be compiled, then it's a 'zero column table'
// this avoids problems when creating the view when opening the
// database
if
(
isRecursiveQueryExceptionDetected
(
createException
)){
this
.
isRecursiveQueryDetected
=
true
;
}
tables
=
New
.
arrayList
();
cols
=
new
Column
[
0
];
if
(
recursive
&&
columnTemplates
!=
null
)
{
...
...
@@ -665,5 +672,32 @@ public class TableView extends Table {
return
true
;
}
}
/**
* Get a list of the tables used by this query (for recursion detection)
* @return
*/
public
List
<
Table
>
getTables
(){
return
tables
;
}
public
boolean
isRecursiveQueryDetected
(){
return
isRecursiveQueryDetected
;
}
private
boolean
isRecursiveQueryExceptionDetected
(
DbException
exception
){
if
(
exception
==
null
){
return
false
;
}
if
(
exception
.
getErrorCode
()!=
ErrorCode
.
TABLE_OR_VIEW_NOT_FOUND_1
){
return
false
;
}
if
(!
exception
.
getMessage
().
contains
(
"\""
+
this
.
getName
()+
"\""
)){
return
false
;
}
return
true
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestGeneralCommonTableQueries.java
浏览文件 @
8ca2feb0
...
...
@@ -51,8 +51,9 @@ public class TestGeneralCommonTableQueries extends TestBase {
* @param a ignored
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
System
.
out
.
println
(
"Testing starting"
);
TestBase
.
createCaller
().
init
().
test
();
//
System.out.println("Testing done");
System
.
out
.
println
(
"Testing done"
);
}
@Override
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论