Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
1a47715d
提交
1a47715d
authored
6月 25, 2010
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Experimental feature to support nested joins.
上级
36560928
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
168 行增加
和
87 行删除
+168
-87
Parser.java
h2/src/main/org/h2/command/Parser.java
+42
-23
Select.java
h2/src/main/org/h2/command/dml/Select.java
+15
-11
Constants.java
h2/src/main/org/h2/engine/Constants.java
+5
-0
ExpressionColumn.java
h2/src/main/org/h2/expression/ExpressionColumn.java
+7
-0
Plan.java
h2/src/main/org/h2/table/Plan.java
+11
-8
RangeTable.java
h2/src/main/org/h2/table/RangeTable.java
+2
-2
TableFilter.java
h2/src/main/org/h2/table/TableFilter.java
+86
-43
没有找到文件。
h2/src/main/org/h2/command/Parser.java
浏览文件 @
1a47715d
...
@@ -124,6 +124,7 @@ import org.h2.table.RangeTable;
...
@@ -124,6 +124,7 @@ import org.h2.table.RangeTable;
import
org.h2.table.Table
;
import
org.h2.table.Table
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableView
;
import
org.h2.table.TableView
;
import
org.h2.table.TableFilter.TableFilterVisitor
;
import
org.h2.util.Utils
;
import
org.h2.util.Utils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.New
;
import
org.h2.util.New
;
...
@@ -969,8 +970,17 @@ public class Parser {
...
@@ -969,8 +970,17 @@ public class Parser {
alias
=
session
.
getNextSystemIdentifier
(
sqlCommand
);
alias
=
session
.
getNextSystemIdentifier
(
sqlCommand
);
table
=
TableView
.
createTempView
(
s
,
session
.
getUser
(),
alias
,
query
,
currentSelect
);
table
=
TableView
.
createTempView
(
s
,
session
.
getUser
(),
alias
,
query
,
currentSelect
);
}
else
{
}
else
{
TableFilter
top
=
readTableFilter
(
fromOuter
);
TableFilter
top
;
top
=
readJoin
(
top
,
currentSelect
,
fromOuter
);
if
(
SysProperties
.
NESTED_JOINS
)
{
String
joinTable
=
Constants
.
PREFIX_JOIN
+
parseIndex
;
top
=
new
TableFilter
(
session
,
getDualTable
(
true
),
joinTable
,
rightsChecked
,
currentSelect
);
TableFilter
n
=
readTableFilter
(
false
);
n
=
readJoin
(
n
,
currentSelect
,
false
);
top
.
addJoin
(
n
,
false
,
true
,
null
);
}
else
{
top
=
readTableFilter
(
fromOuter
);
top
=
readJoin
(
top
,
currentSelect
,
fromOuter
);
}
read
(
")"
);
read
(
")"
);
alias
=
readFromAlias
(
null
);
alias
=
readFromAlias
(
null
);
if
(
alias
!=
null
)
{
if
(
alias
!=
null
)
{
...
@@ -988,7 +998,7 @@ public class Parser {
...
@@ -988,7 +998,7 @@ public class Parser {
read
(
","
);
read
(
","
);
Expression
max
=
readExpression
();
Expression
max
=
readExpression
();
read
(
")"
);
read
(
")"
);
table
=
new
RangeTable
(
mainSchema
,
min
,
max
);
table
=
new
RangeTable
(
mainSchema
,
min
,
max
,
false
);
}
else
{
}
else
{
Expression
func
=
readFunction
(
schema
,
tableName
);
Expression
func
=
readFunction
(
schema
,
tableName
);
if
(!(
func
instanceof
FunctionCall
))
{
if
(!(
func
instanceof
FunctionCall
))
{
...
@@ -997,7 +1007,7 @@ public class Parser {
...
@@ -997,7 +1007,7 @@ public class Parser {
table
=
new
FunctionTable
(
mainSchema
,
session
,
func
,
(
FunctionCall
)
func
);
table
=
new
FunctionTable
(
mainSchema
,
session
,
func
,
(
FunctionCall
)
func
);
}
}
}
else
if
(
equalsToken
(
"DUAL"
,
tableName
))
{
}
else
if
(
equalsToken
(
"DUAL"
,
tableName
))
{
table
=
getDualTable
();
table
=
getDualTable
(
false
);
}
else
{
}
else
{
table
=
readTableOrView
(
tableName
);
table
=
readTableOrView
(
tableName
);
}
}
...
@@ -1233,7 +1243,14 @@ public class Parser {
...
@@ -1233,7 +1243,14 @@ public class Parser {
if
(
readIf
(
"ON"
))
{
if
(
readIf
(
"ON"
))
{
on
=
readExpression
();
on
=
readExpression
();
}
}
newTop
.
addJoin
(
top
,
true
,
fromOuter
,
on
);
if
(
SysProperties
.
NESTED_JOINS
)
{
String
joinTable
=
Constants
.
PREFIX_JOIN
+
parseIndex
;
TableFilter
nt
=
new
TableFilter
(
session
,
getDualTable
(
true
),
joinTable
,
rightsChecked
,
currentSelect
);
nt
.
addJoin
(
top
,
false
,
true
,
null
);
newTop
.
addJoin
(
nt
,
true
,
false
,
on
);
}
else
{
newTop
.
addJoin
(
top
,
true
,
false
,
on
);
}
top
=
newTop
;
top
=
newTop
;
last
=
newTop
;
last
=
newTop
;
}
else
if
(
readIf
(
"LEFT"
))
{
}
else
if
(
readIf
(
"LEFT"
))
{
...
@@ -1245,7 +1262,7 @@ public class Parser {
...
@@ -1245,7 +1262,7 @@ public class Parser {
if
(
readIf
(
"ON"
))
{
if
(
readIf
(
"ON"
))
{
on
=
readExpression
();
on
=
readExpression
();
}
}
top
.
addJoin
(
join
,
true
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
true
,
f
alse
,
on
);
last
=
join
;
last
=
join
;
}
else
if
(
readIf
(
"FULL"
))
{
}
else
if
(
readIf
(
"FULL"
))
{
throw
getSyntaxError
();
throw
getSyntaxError
();
...
@@ -1258,9 +1275,9 @@ public class Parser {
...
@@ -1258,9 +1275,9 @@ public class Parser {
on
=
readExpression
();
on
=
readExpression
();
}
}
if
(
SysProperties
.
NESTED_JOINS
)
{
if
(
SysProperties
.
NESTED_JOINS
)
{
top
.
addJoin
(
join
,
false
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
false
,
f
alse
,
on
);
}
else
{
}
else
{
top
.
addJoin
(
join
,
fromOuter
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
fromOuter
,
f
alse
,
on
);
}
}
last
=
join
;
last
=
join
;
}
else
if
(
readIf
(
"JOIN"
))
{
}
else
if
(
readIf
(
"JOIN"
))
{
...
@@ -1271,18 +1288,18 @@ public class Parser {
...
@@ -1271,18 +1288,18 @@ public class Parser {
on
=
readExpression
();
on
=
readExpression
();
}
}
if
(
SysProperties
.
NESTED_JOINS
)
{
if
(
SysProperties
.
NESTED_JOINS
)
{
top
.
addJoin
(
join
,
false
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
false
,
f
alse
,
on
);
}
else
{
}
else
{
top
.
addJoin
(
join
,
fromOuter
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
fromOuter
,
f
alse
,
on
);
}
}
last
=
join
;
last
=
join
;
}
else
if
(
readIf
(
"CROSS"
))
{
}
else
if
(
readIf
(
"CROSS"
))
{
read
(
"JOIN"
);
read
(
"JOIN"
);
TableFilter
join
=
readTableFilter
(
fromOuter
);
TableFilter
join
=
readTableFilter
(
fromOuter
);
if
(
SysProperties
.
NESTED_JOINS
)
{
if
(
SysProperties
.
NESTED_JOINS
)
{
top
.
addJoin
(
join
,
false
,
f
romOuter
,
null
);
top
.
addJoin
(
join
,
false
,
f
alse
,
null
);
}
else
{
}
else
{
top
.
addJoin
(
join
,
fromOuter
,
f
romOuter
,
null
);
top
.
addJoin
(
join
,
fromOuter
,
f
alse
,
null
);
}
}
last
=
join
;
last
=
join
;
}
else
if
(
readIf
(
"NATURAL"
))
{
}
else
if
(
readIf
(
"NATURAL"
))
{
...
@@ -1313,9 +1330,9 @@ public class Parser {
...
@@ -1313,9 +1330,9 @@ public class Parser {
}
}
}
}
if
(
SysProperties
.
NESTED_JOINS
)
{
if
(
SysProperties
.
NESTED_JOINS
)
{
top
.
addJoin
(
join
,
false
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
false
,
f
alse
,
on
);
}
else
{
}
else
{
top
.
addJoin
(
join
,
fromOuter
,
f
romOuter
,
on
);
top
.
addJoin
(
join
,
fromOuter
,
f
alse
,
on
);
}
}
last
=
join
;
last
=
join
;
}
else
{
}
else
{
...
@@ -1558,16 +1575,18 @@ public class Parser {
...
@@ -1558,16 +1575,18 @@ public class Parser {
}
while
(
readIf
(
","
));
}
while
(
readIf
(
","
));
}
}
private
void
parseJoinTableFilter
(
TableFilter
top
,
Select
command
)
{
private
void
parseJoinTableFilter
(
TableFilter
top
,
final
Select
command
)
{
top
=
readJoin
(
top
,
command
,
top
.
isJoinOuter
());
top
=
readJoin
(
top
,
command
,
top
.
isJoinOuter
());
command
.
addTableFilter
(
top
,
true
);
command
.
addTableFilter
(
top
,
true
);
boolean
isOuter
=
false
;
boolean
isOuter
=
false
;
while
(
true
)
{
while
(
true
)
{
for
(
TableFilter
n
=
top
.
getNestedJoin
();
n
!=
null
;
n
=
n
.
getNestedJoin
())
{
TableFilter
n
=
top
.
getNestedJoin
();
command
.
addTableFilter
(
n
,
false
);
if
(
n
!=
null
)
{
for
(
TableFilter
j
=
n
.
getJoin
();
j
!=
null
;
j
=
j
.
getJoin
())
{
n
.
visit
(
new
TableFilterVisitor
()
{
command
.
addTableFilter
(
j
,
false
);
public
void
accept
(
TableFilter
f
)
{
}
command
.
addTableFilter
(
f
,
false
);
}
});
}
}
TableFilter
join
=
top
.
getJoin
();
TableFilter
join
=
top
.
getJoin
();
if
(
join
==
null
)
{
if
(
join
==
null
)
{
...
@@ -1652,7 +1671,7 @@ public class Parser {
...
@@ -1652,7 +1671,7 @@ public class Parser {
if
(!
readIf
(
"FROM"
))
{
if
(!
readIf
(
"FROM"
))
{
// select without FROM: convert to SELECT ... FROM
// select without FROM: convert to SELECT ... FROM
// SYSTEM_RANGE(1,1)
// SYSTEM_RANGE(1,1)
Table
dual
=
getDualTable
();
Table
dual
=
getDualTable
(
false
);
TableFilter
filter
=
new
TableFilter
(
session
,
dual
,
null
,
rightsChecked
,
currentSelect
);
TableFilter
filter
=
new
TableFilter
(
session
,
dual
,
null
,
rightsChecked
,
currentSelect
);
command
.
addTableFilter
(
filter
,
true
);
command
.
addTableFilter
(
filter
,
true
);
}
else
{
}
else
{
...
@@ -1688,10 +1707,10 @@ public class Parser {
...
@@ -1688,10 +1707,10 @@ public class Parser {
return
command
;
return
command
;
}
}
private
Table
getDualTable
()
{
private
Table
getDualTable
(
boolean
noColumns
)
{
Schema
main
=
database
.
findSchema
(
Constants
.
SCHEMA_MAIN
);
Schema
main
=
database
.
findSchema
(
Constants
.
SCHEMA_MAIN
);
Expression
one
=
ValueExpression
.
get
(
ValueLong
.
get
(
1
));
Expression
one
=
ValueExpression
.
get
(
ValueLong
.
get
(
1
));
return
new
RangeTable
(
main
,
one
,
one
);
return
new
RangeTable
(
main
,
one
,
one
,
noColumns
);
}
}
private
void
setSQL
(
Prepared
command
,
String
start
,
int
startIndex
)
{
private
void
setSQL
(
Prepared
command
,
String
start
,
int
startIndex
)
{
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
1a47715d
...
@@ -845,27 +845,35 @@ public class Select extends Query {
...
@@ -845,27 +845,35 @@ public class Select extends Query {
optimizer
.
optimize
();
optimizer
.
optimize
();
topTableFilter
=
optimizer
.
getTopFilter
();
topTableFilter
=
optimizer
.
getTopFilter
();
double
planCost
=
optimizer
.
getCost
();
double
planCost
=
optimizer
.
getCost
();
setEvaluatableRecursive
(
topTableFilter
);
setEvaluatableRecursive
(
topTableFilter
);
topTableFilter
.
prepare
();
topTableFilter
.
prepare
();
return
planCost
;
return
planCost
;
}
}
private
void
setEvaluatableRecursive
(
TableFilter
f
)
{
private
void
setEvaluatableRecursive
(
TableFilter
f
)
{
for
(;
f
!=
null
;
f
=
f
.
getJoin
())
{
for
(;
f
!=
null
;
f
=
f
.
getJoin
())
{
f
.
setEvaluatable
(
f
,
true
);
f
.
setEvaluatable
(
f
,
true
);
if
(
condition
!=
null
)
{
if
(
condition
!=
null
)
{
condition
.
setEvaluatable
(
f
,
true
);
condition
.
setEvaluatable
(
f
,
true
);
}
}
TableFilter
n
=
f
.
getNestedJoin
();
if
(
n
!=
null
)
{
setEvaluatableRecursive
(
n
);
}
Expression
on
=
f
.
getJoinCondition
();
Expression
on
=
f
.
getJoinCondition
();
if
(
on
!=
null
)
{
if
(
on
!=
null
)
{
if
(!
on
.
isEverything
(
ExpressionVisitor
.
EVALUATABLE
))
{
if
(!
on
.
isEverything
(
ExpressionVisitor
.
EVALUATABLE
))
{
if
(
f
.
isJoinOuter
())
{
if
(
SysProperties
.
NESTED_JOINS
)
{
// this will check if all columns exist - it may or may not throw an exception
int
testCanSupport
;
on
=
on
.
optimize
(
session
);
}
else
{
// it is not supported even if the columns exist
if
(
f
.
isJoinOuter
())
{
throw
DbException
.
get
(
ErrorCode
.
UNSUPPORTED_OUTER_JOIN_CONDITION_1
,
on
.
getSQL
());
// this will check if all columns exist - it may or may not throw an exception
on
=
on
.
optimize
(
session
);
// it is not supported even if the columns exist
throw
DbException
.
get
(
ErrorCode
.
UNSUPPORTED_OUTER_JOIN_CONDITION_1
,
on
.
getSQL
());
}
}
}
f
.
removeJoinCondition
();
f
.
removeJoinCondition
();
// need to check that all added are bound to a table
// need to check that all added are bound to a table
...
@@ -885,10 +893,6 @@ public class Select extends Query {
...
@@ -885,10 +893,6 @@ public class Select extends Query {
for
(
Expression
e
:
expressions
)
{
for
(
Expression
e
:
expressions
)
{
e
.
setEvaluatable
(
f
,
true
);
e
.
setEvaluatable
(
f
,
true
);
}
}
TableFilter
n
=
f
.
getNestedJoin
();
if
(
n
!=
null
)
{
setEvaluatableRecursive
(
n
);
}
}
}
}
}
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
1a47715d
...
@@ -222,6 +222,11 @@ public class Constants {
...
@@ -222,6 +222,11 @@ public class Constants {
*/
*/
public
static
final
String
PREFIX_INDEX
=
"INDEX_"
;
public
static
final
String
PREFIX_INDEX
=
"INDEX_"
;
/**
* The name prefix used for synthetic nested join tables.
*/
public
static
final
String
PREFIX_JOIN
=
"SYSTEM_JOIN_"
;
/**
/**
* The name prefix used for primary key constraints that are not explicitly
* The name prefix used for primary key constraints that are not explicitly
* named.
* named.
...
...
h2/src/main/org/h2/expression/ExpressionColumn.java
浏览文件 @
1a47715d
...
@@ -11,6 +11,7 @@ import org.h2.command.Parser;
...
@@ -11,6 +11,7 @@ import org.h2.command.Parser;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectListColumnResolver
;
import
org.h2.command.dml.SelectListColumnResolver
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.index.IndexCondition
;
import
org.h2.index.IndexCondition
;
...
@@ -244,6 +245,12 @@ public class ExpressionColumn extends Expression {
...
@@ -244,6 +245,12 @@ public class ExpressionColumn extends Expression {
// if the current value is known (evaluatable set)
// if the current value is known (evaluatable set)
// or if this columns belongs to a 'higher level' query and is
// or if this columns belongs to a 'higher level' query and is
// therefore just a parameter
// therefore just a parameter
if
(
SysProperties
.
NESTED_JOINS
)
{
if
(
getTableFilter
()
==
null
)
{
return
false
;
}
return
getTableFilter
().
isEvaluatable
();
}
return
evaluatable
||
visitor
.
getQueryLevel
()
<
this
.
queryLevel
;
return
evaluatable
||
visitor
.
getQueryLevel
()
<
this
.
queryLevel
;
case
ExpressionVisitor
.
SET_MAX_DATA_MODIFICATION_ID
:
case
ExpressionVisitor
.
SET_MAX_DATA_MODIFICATION_ID
:
visitor
.
addDataModificationId
(
column
.
getTable
().
getMaxDataModificationId
());
visitor
.
addDataModificationId
(
column
.
getTable
().
getMaxDataModificationId
());
...
...
h2/src/main/org/h2/table/Plan.java
浏览文件 @
1a47715d
...
@@ -11,6 +11,7 @@ import java.util.HashMap;
...
@@ -11,6 +11,7 @@ import java.util.HashMap;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.table.TableFilter.TableFilterVisitor
;
import
org.h2.util.New
;
import
org.h2.util.New
;
/**
/**
...
@@ -33,20 +34,21 @@ public class Plan {
...
@@ -33,20 +34,21 @@ public class Plan {
public
Plan
(
TableFilter
[]
filters
,
int
count
,
Expression
condition
)
{
public
Plan
(
TableFilter
[]
filters
,
int
count
,
Expression
condition
)
{
this
.
filters
=
new
TableFilter
[
count
];
this
.
filters
=
new
TableFilter
[
count
];
System
.
arraycopy
(
filters
,
0
,
this
.
filters
,
0
,
count
);
System
.
arraycopy
(
filters
,
0
,
this
.
filters
,
0
,
count
);
ArrayList
<
Expression
>
allCond
=
New
.
arrayList
();
final
ArrayList
<
Expression
>
allCond
=
New
.
arrayList
();
ArrayList
<
TableFilter
>
all
=
New
.
arrayList
();
final
ArrayList
<
TableFilter
>
all
=
New
.
arrayList
();
if
(
condition
!=
null
)
{
if
(
condition
!=
null
)
{
allCond
.
add
(
condition
);
allCond
.
add
(
condition
);
}
}
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
TableFilter
f
=
filters
[
i
];
TableFilter
f
=
filters
[
i
];
do
{
f
.
visit
(
new
TableFilterVisitor
()
{
all
.
add
(
f
);
public
void
accept
(
TableFilter
f
)
{
if
(
f
.
getJoinCondition
()
!=
null
)
{
all
.
add
(
f
);
allCond
.
add
(
f
.
getJoinCondition
());
if
(
f
.
getJoinCondition
()
!=
null
)
{
allCond
.
add
(
f
.
getJoinCondition
());
}
}
}
f
=
f
.
getJoin
();
});
}
while
(
f
!=
null
);
}
}
allConditions
=
new
Expression
[
allCond
.
size
()];
allConditions
=
new
Expression
[
allCond
.
size
()];
allCond
.
toArray
(
allConditions
);
allCond
.
toArray
(
allConditions
);
...
@@ -126,6 +128,7 @@ public class Plan {
...
@@ -126,6 +128,7 @@ public class Plan {
}
}
private
void
setEvaluatable
(
TableFilter
filter
,
boolean
b
)
{
private
void
setEvaluatable
(
TableFilter
filter
,
boolean
b
)
{
filter
.
setEvaluatable
(
filter
,
b
);
for
(
Expression
e
:
allConditions
)
{
for
(
Expression
e
:
allConditions
)
{
e
.
setEvaluatable
(
filter
,
b
);
e
.
setEvaluatable
(
filter
,
b
);
}
}
...
...
h2/src/main/org/h2/table/RangeTable.java
浏览文件 @
1a47715d
...
@@ -38,9 +38,9 @@ public class RangeTable extends Table {
...
@@ -38,9 +38,9 @@ public class RangeTable extends Table {
* @param min the start expression
* @param min the start expression
* @param max the end expression
* @param max the end expression
*/
*/
public
RangeTable
(
Schema
schema
,
Expression
min
,
Expression
max
)
{
public
RangeTable
(
Schema
schema
,
Expression
min
,
Expression
max
,
boolean
noColumns
)
{
super
(
schema
,
0
,
NAME
,
true
,
true
);
super
(
schema
,
0
,
NAME
,
true
,
true
);
Column
[]
cols
=
{
new
Column
(
"X"
,
Value
.
LONG
)
};
Column
[]
cols
=
noColumns
?
new
Column
[
0
]
:
new
Column
[]
{
new
Column
(
"X"
,
Value
.
LONG
)
};
this
.
min
=
min
;
this
.
min
=
min
;
this
.
max
=
max
;
this
.
max
=
max
;
setColumns
(
cols
);
setColumns
(
cols
);
...
...
h2/src/main/org/h2/table/TableFilter.java
浏览文件 @
1a47715d
...
@@ -40,6 +40,7 @@ public class TableFilter implements ColumnResolver {
...
@@ -40,6 +40,7 @@ public class TableFilter implements ColumnResolver {
private
Session
session
;
private
Session
session
;
private
Index
index
;
private
Index
index
;
private
int
scanCount
;
private
int
scanCount
;
private
boolean
evaluatable
;
/**
/**
* Indicates that this filter is used in the plan.
* Indicates that this filter is used in the plan.
...
@@ -70,22 +71,22 @@ public class TableFilter implements ColumnResolver {
...
@@ -70,22 +71,22 @@ public class TableFilter implements ColumnResolver {
private
SearchRow
currentSearchRow
;
private
SearchRow
currentSearchRow
;
private
Row
current
;
private
Row
current
;
private
int
state
;
private
int
state
;
/**
/**
* The joined table (if there is one).
* The joined table (if there is one).
*/
*/
private
TableFilter
join
;
private
TableFilter
join
;
/**
/**
* Whether this table is an outer join.
* Whether this table is an outer join.
*/
*/
private
boolean
joinOuter
;
private
boolean
joinOuter
;
/**
/**
* The nested joined table (if there is one).
* The nested joined table (if there is one).
*/
*/
private
TableFilter
nestedJoin
;
private
TableFilter
nestedJoin
;
private
ArrayList
<
Column
>
naturalJoinColumns
;
private
ArrayList
<
Column
>
naturalJoinColumns
;
private
boolean
foundOne
;
private
boolean
foundOne
;
private
Expression
fullCondition
;
private
Expression
fullCondition
;
...
@@ -186,6 +187,10 @@ public class TableFilter implements ColumnResolver {
...
@@ -186,6 +187,10 @@ public class TableFilter implements ColumnResolver {
}
}
private
void
setEvaluatable
(
TableFilter
join
)
{
private
void
setEvaluatable
(
TableFilter
join
)
{
if
(
SysProperties
.
NESTED_JOINS
)
{
setEvaluatable
(
true
);
return
;
}
// this table filter is now evaluatable - in all sub-joins
// this table filter is now evaluatable - in all sub-joins
do
{
do
{
Expression
e
=
join
.
getJoinCondition
();
Expression
e
=
join
.
getJoinCondition
();
...
@@ -306,25 +311,8 @@ public class TableFilter implements ColumnResolver {
...
@@ -306,25 +311,8 @@ public class TableFilter implements ColumnResolver {
}
else
{
}
else
{
// state == FOUND || NULL_ROW
// state == FOUND || NULL_ROW
// the last row was ok - try next row of the join
// the last row was ok - try next row of the join
if
(
nestedJoin
!=
null
)
{
if
(
join
!=
null
&&
join
.
next
())
{
if
(
join
==
null
)
{
return
true
;
if
(
nestedJoin
.
next
())
{
return
true
;
}
}
else
{
while
(
true
)
{
if
(
nestedJoin
.
next
())
{
if
(
join
.
next
())
{
return
true
;
}
join
.
reset
();
}
}
}
}
else
{
if
(
join
!=
null
&&
join
.
next
())
{
return
true
;
}
}
}
}
}
while
(
true
)
{
while
(
true
)
{
...
@@ -334,6 +322,10 @@ public class TableFilter implements ColumnResolver {
...
@@ -334,6 +322,10 @@ public class TableFilter implements ColumnResolver {
}
}
if
(
cursor
.
isAlwaysFalse
())
{
if
(
cursor
.
isAlwaysFalse
())
{
state
=
AFTER_LAST
;
state
=
AFTER_LAST
;
}
else
if
(
nestedJoin
!=
null
)
{
if
(
state
==
BEFORE_FIRST
)
{
state
=
FOUND
;
}
}
else
{
}
else
{
if
((++
scanCount
&
4095
)
==
0
)
{
if
((++
scanCount
&
4095
)
==
0
)
{
checkTimeout
();
checkTimeout
();
...
@@ -346,6 +338,16 @@ public class TableFilter implements ColumnResolver {
...
@@ -346,6 +338,16 @@ public class TableFilter implements ColumnResolver {
state
=
AFTER_LAST
;
state
=
AFTER_LAST
;
}
}
}
}
if
(
nestedJoin
!=
null
&&
state
==
FOUND
)
{
if
(!
nestedJoin
.
next
())
{
state
=
AFTER_LAST
;
if
(
joinOuter
&&
!
foundOne
)
{
// possibly null row
}
else
{
continue
;
}
}
}
// if no more rows found, try the null row (for outer joins only)
// if no more rows found, try the null row (for outer joins only)
if
(
state
==
AFTER_LAST
)
{
if
(
state
==
AFTER_LAST
)
{
if
(
joinOuter
&&
!
foundOne
)
{
if
(
joinOuter
&&
!
foundOne
)
{
...
@@ -354,12 +356,6 @@ public class TableFilter implements ColumnResolver {
...
@@ -354,12 +356,6 @@ public class TableFilter implements ColumnResolver {
break
;
break
;
}
}
}
}
if
(
state
==
FOUND
&&
nestedJoin
!=
null
)
{
nestedJoin
.
reset
();
if
(!
nestedJoin
.
next
())
{
continue
;
}
}
if
(!
isOk
(
filterCondition
))
{
if
(!
isOk
(
filterCondition
))
{
continue
;
continue
;
}
}
...
@@ -385,14 +381,17 @@ public class TableFilter implements ColumnResolver {
...
@@ -385,14 +381,17 @@ public class TableFilter implements ColumnResolver {
state
=
AFTER_LAST
;
state
=
AFTER_LAST
;
return
false
;
return
false
;
}
}
pr
ivate
void
setNullRow
()
{
pr
otected
void
setNullRow
()
{
state
=
NULL_ROW
;
state
=
NULL_ROW
;
current
=
table
.
getNullRow
();
current
=
table
.
getNullRow
();
currentSearchRow
=
current
;
currentSearchRow
=
current
;
if
(
nestedJoin
!=
null
)
{
if
(
nestedJoin
!=
null
)
{
int
todoRecurse
;
nestedJoin
.
visit
(
new
TableFilterVisitor
()
{
nestedJoin
.
setNullRow
();
public
void
accept
(
TableFilter
f
)
{
f
.
setNullRow
();
}
});
}
}
}
}
...
@@ -484,9 +483,21 @@ public class TableFilter implements ColumnResolver {
...
@@ -484,9 +483,21 @@ public class TableFilter implements ColumnResolver {
* @param outer if this is an outer join
* @param outer if this is an outer join
* @param on the join condition
* @param on the join condition
*/
*/
public
void
addJoin
(
TableFilter
filter
,
boolean
outer
,
boolean
nested
,
Expression
on
)
{
public
void
addJoin
(
TableFilter
filter
,
boolean
outer
,
boolean
nested
,
final
Expression
on
)
{
if
(
on
!=
null
)
{
if
(
on
!=
null
)
{
on
.
mapColumns
(
this
,
0
);
on
.
mapColumns
(
this
,
0
);
if
(
SysProperties
.
NESTED_JOINS
)
{
visit
(
new
TableFilterVisitor
()
{
public
void
accept
(
TableFilter
f
)
{
on
.
mapColumns
(
f
,
0
);
}
});
filter
.
visit
(
new
TableFilterVisitor
()
{
public
void
accept
(
TableFilter
f
)
{
on
.
mapColumns
(
f
,
0
);
}
});
}
}
}
if
(
nested
&&
SysProperties
.
NESTED_JOINS
)
{
if
(
nested
&&
SysProperties
.
NESTED_JOINS
)
{
if
(
nestedJoin
!=
null
)
{
if
(
nestedJoin
!=
null
)
{
...
@@ -529,9 +540,6 @@ public class TableFilter implements ColumnResolver {
...
@@ -529,9 +540,6 @@ public class TableFilter implements ColumnResolver {
on
.
mapColumns
(
this
,
0
);
on
.
mapColumns
(
this
,
0
);
addFilterCondition
(
on
,
true
);
addFilterCondition
(
on
,
true
);
on
.
createIndexConditions
(
session
,
this
);
on
.
createIndexConditions
(
session
,
this
);
if
(
nestedJoin
!=
null
)
{
nestedJoin
.
mapAndAddFilter
(
on
);
}
if
(
join
!=
null
)
{
if
(
join
!=
null
)
{
join
.
mapAndAddFilter
(
on
);
join
.
mapAndAddFilter
(
on
);
}
}
...
@@ -566,7 +574,22 @@ public class TableFilter implements ColumnResolver {
...
@@ -566,7 +574,22 @@ public class TableFilter implements ColumnResolver {
}
}
}
}
if
(
nestedJoin
!=
null
)
{
if
(
nestedJoin
!=
null
)
{
buff
.
append
(
"("
);
buff
.
append
(
"(\n"
);
TableFilter
n
=
nestedJoin
;
do
{
buff
.
append
(
n
.
getPlanSQL
(
n
!=
nestedJoin
));
buff
.
append
(
"\n"
);
n
=
(
TableFilter
)
n
.
getJoin
();
}
while
(
n
!=
null
);
buff
.
append
(
") ON "
);
if
(
joinCondition
==
null
)
{
// need to have a ON expression,
// otherwise the nesting is unclear
buff
.
append
(
"1=1"
);
}
else
{
buff
.
append
(
StringUtils
.
unEnclose
(
joinCondition
.
getSQL
()));
}
return
buff
.
toString
();
}
}
buff
.
append
(
table
.
getSQL
());
buff
.
append
(
table
.
getSQL
());
if
(
alias
!=
null
)
{
if
(
alias
!=
null
)
{
...
@@ -586,11 +609,6 @@ public class TableFilter implements ColumnResolver {
...
@@ -586,11 +609,6 @@ public class TableFilter implements ColumnResolver {
String
plan
=
StringUtils
.
quoteRemarkSQL
(
planBuff
.
toString
());
String
plan
=
StringUtils
.
quoteRemarkSQL
(
planBuff
.
toString
());
buff
.
append
(
plan
).
append
(
" */"
);
buff
.
append
(
plan
).
append
(
" */"
);
}
}
if
(
nestedJoin
!=
null
)
{
buff
.
append
(
'\n'
);
buff
.
append
(
nestedJoin
.
getPlanSQL
(
true
));
buff
.
append
(
")"
);
}
if
(
isJoin
)
{
if
(
isJoin
)
{
buff
.
append
(
" ON "
);
buff
.
append
(
" ON "
);
if
(
joinCondition
==
null
)
{
if
(
joinCondition
==
null
)
{
...
@@ -713,6 +731,7 @@ public class TableFilter implements ColumnResolver {
...
@@ -713,6 +731,7 @@ public class TableFilter implements ColumnResolver {
* @param b the new flag
* @param b the new flag
*/
*/
public
void
setEvaluatable
(
TableFilter
filter
,
boolean
b
)
{
public
void
setEvaluatable
(
TableFilter
filter
,
boolean
b
)
{
setEvaluatable
(
b
);
if
(
filterCondition
!=
null
)
{
if
(
filterCondition
!=
null
)
{
filterCondition
.
setEvaluatable
(
filter
,
b
);
filterCondition
.
setEvaluatable
(
filter
,
b
);
}
}
...
@@ -727,6 +746,10 @@ public class TableFilter implements ColumnResolver {
...
@@ -727,6 +746,10 @@ public class TableFilter implements ColumnResolver {
}
}
}
}
public
void
setEvaluatable
(
boolean
evaluatable
)
{
this
.
evaluatable
=
evaluatable
;
}
public
String
getSchemaName
()
{
public
String
getSchemaName
()
{
return
table
.
getSchema
().
getName
();
return
table
.
getSchema
().
getName
();
}
}
...
@@ -855,4 +878,24 @@ public class TableFilter implements ColumnResolver {
...
@@ -855,4 +878,24 @@ public class TableFilter implements ColumnResolver {
return
nestedJoin
;
return
nestedJoin
;
}
}
public
void
visit
(
TableFilterVisitor
visitor
)
{
TableFilter
f
=
this
;
do
{
visitor
.
accept
(
f
);
TableFilter
n
=
f
.
nestedJoin
;
if
(
n
!=
null
)
{
n
.
visit
(
visitor
);
}
f
=
(
TableFilter
)
f
.
join
;
}
while
(
f
!=
null
);
}
public
static
interface
TableFilterVisitor
{
public
void
accept
(
TableFilter
f
);
}
public
boolean
isEvaluatable
()
{
return
evaluatable
;
}
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论