Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
877c03fb
提交
877c03fb
authored
8 年前
作者:
Sergi Vladykin
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
https://github.com/h2database/h2database
into lazyQuery
上级
b9dc4892
267e7083
显示空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
79 行增加
和
31 行删除
+79
-31
Select.java
h2/src/main/org/h2/command/dml/Select.java
+1
-1
Aggregate.java
h2/src/main/org/h2/expression/Aggregate.java
+4
-4
BaseIndex.java
h2/src/main/org/h2/index/BaseIndex.java
+5
-0
Index.java
h2/src/main/org/h2/index/Index.java
+8
-0
MetaIndex.java
h2/src/main/org/h2/index/MetaIndex.java
+8
-0
MultiVersionIndex.java
h2/src/main/org/h2/index/MultiVersionIndex.java
+5
-0
PageDataIndex.java
h2/src/main/org/h2/index/PageDataIndex.java
+5
-0
PageDelegateIndex.java
h2/src/main/org/h2/index/PageDelegateIndex.java
+5
-0
ScanIndex.java
h2/src/main/org/h2/index/ScanIndex.java
+5
-0
MVDelegateIndex.java
h2/src/main/org/h2/mvstore/db/MVDelegateIndex.java
+5
-0
MVPrimaryIndex.java
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
+5
-0
Table.java
h2/src/main/org/h2/table/Table.java
+19
-7
TestIndexHints.java
h2/src/test/org/h2/test/db/TestIndexHints.java
+4
-19
没有找到文件。
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
877c03fb
...
@@ -872,7 +872,7 @@ public class Select extends Query {
...
@@ -872,7 +872,7 @@ public class Select extends Query {
Column
column
=
((
ExpressionColumn
)
expr
).
getColumn
();
Column
column
=
((
ExpressionColumn
)
expr
).
getColumn
();
int
selectivity
=
column
.
getSelectivity
();
int
selectivity
=
column
.
getSelectivity
();
Index
columnIndex
=
topTableFilter
.
getTable
().
Index
columnIndex
=
topTableFilter
.
getTable
().
getIndexForColumn
(
column
);
getIndexForColumn
(
column
,
false
,
true
);
if
(
columnIndex
!=
null
&&
if
(
columnIndex
!=
null
&&
selectivity
!=
Constants
.
SELECTIVITY_DEFAULT
&&
selectivity
!=
Constants
.
SELECTIVITY_DEFAULT
&&
selectivity
<
20
)
{
selectivity
<
20
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Aggregate.java
浏览文件 @
877c03fb
...
@@ -287,7 +287,7 @@ public class Aggregate extends Expression {
...
@@ -287,7 +287,7 @@ public class Aggregate extends Expression {
case
MIN:
case
MIN:
case
MAX:
case
MAX:
boolean
first
=
type
==
MIN
;
boolean
first
=
type
==
MIN
;
Index
index
=
getColumnIndex
();
Index
index
=
get
MinMax
ColumnIndex
();
int
sortType
=
index
.
getIndexColumns
()[
0
].
sortType
;
int
sortType
=
index
.
getIndexColumns
()[
0
].
sortType
;
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
first
=
!
first
;
first
=
!
first
;
...
@@ -575,14 +575,14 @@ public class Aggregate extends Expression {
...
@@ -575,14 +575,14 @@ public class Aggregate extends Expression {
return
text
+
StringUtils
.
enclose
(
on
.
getSQL
());
return
text
+
StringUtils
.
enclose
(
on
.
getSQL
());
}
}
private
Index
getColumnIndex
()
{
private
Index
get
MinMax
ColumnIndex
()
{
if
(
on
instanceof
ExpressionColumn
)
{
if
(
on
instanceof
ExpressionColumn
)
{
ExpressionColumn
col
=
(
ExpressionColumn
)
on
;
ExpressionColumn
col
=
(
ExpressionColumn
)
on
;
Column
column
=
col
.
getColumn
();
Column
column
=
col
.
getColumn
();
TableFilter
filter
=
col
.
getTableFilter
();
TableFilter
filter
=
col
.
getTableFilter
();
if
(
filter
!=
null
)
{
if
(
filter
!=
null
)
{
Table
table
=
filter
.
getTable
();
Table
table
=
filter
.
getTable
();
Index
index
=
table
.
getIndexForColumn
(
column
);
Index
index
=
table
.
getIndexForColumn
(
column
,
true
,
false
);
return
index
;
return
index
;
}
}
}
}
...
@@ -602,7 +602,7 @@ public class Aggregate extends Expression {
...
@@ -602,7 +602,7 @@ public class Aggregate extends Expression {
return
visitor
.
getTable
().
canGetRowCount
();
return
visitor
.
getTable
().
canGetRowCount
();
case
MIN:
case
MIN:
case
MAX:
case
MAX:
Index
index
=
getColumnIndex
();
Index
index
=
get
MinMax
ColumnIndex
();
return
index
!=
null
;
return
index
!=
null
;
default
:
default
:
return
false
;
return
false
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/BaseIndex.java
浏览文件 @
877c03fb
...
@@ -377,6 +377,11 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
...
@@ -377,6 +377,11 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
return
-
1
;
return
-
1
;
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
column
.
equals
(
columns
[
0
]);
}
/**
/**
* Get the list of columns as a string.
* Get the list of columns as a string.
*
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/Index.java
浏览文件 @
877c03fb
...
@@ -190,6 +190,14 @@ public interface Index extends SchemaObject {
...
@@ -190,6 +190,14 @@ public interface Index extends SchemaObject {
*/
*/
int
getColumnIndex
(
Column
col
);
int
getColumnIndex
(
Column
col
);
/**
* Check if the given column is the first for this index
*
* @param column the column
* @return true if the given columns is the first
*/
boolean
isFirstColumn
(
Column
column
);
/**
/**
* Get the indexed columns as index columns (with ordering information).
* Get the indexed columns as index columns (with ordering information).
*
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/MetaIndex.java
浏览文件 @
877c03fb
...
@@ -82,6 +82,14 @@ public class MetaIndex extends BaseIndex {
...
@@ -82,6 +82,14 @@ public class MetaIndex extends BaseIndex {
return
super
.
getColumnIndex
(
col
);
return
super
.
getColumnIndex
(
col
);
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
if
(
scan
)
{
return
false
;
}
return
super
.
isFirstColumn
(
column
);
}
@Override
@Override
public
void
checkRename
()
{
public
void
checkRename
()
{
throw
DbException
.
getUnsupportedException
(
"META"
);
throw
DbException
.
getUnsupportedException
(
"META"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/MultiVersionIndex.java
浏览文件 @
877c03fb
...
@@ -230,6 +230,11 @@ public class MultiVersionIndex implements Index {
...
@@ -230,6 +230,11 @@ public class MultiVersionIndex implements Index {
return
base
.
getColumnIndex
(
col
);
return
base
.
getColumnIndex
(
col
);
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
base
.
isFirstColumn
(
column
);
}
@Override
@Override
public
Column
[]
getColumns
()
{
public
Column
[]
getColumns
()
{
return
base
.
getColumns
();
return
base
.
getColumns
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageDataIndex.java
浏览文件 @
877c03fb
...
@@ -464,6 +464,11 @@ public class PageDataIndex extends PageIndex {
...
@@ -464,6 +464,11 @@ public class PageDataIndex extends PageIndex {
return
-
1
;
return
-
1
;
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
false
;
}
@Override
@Override
public
void
close
(
Session
session
)
{
public
void
close
(
Session
session
)
{
if
(
trace
.
isDebugEnabled
())
{
if
(
trace
.
isDebugEnabled
())
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageDelegateIndex.java
浏览文件 @
877c03fb
...
@@ -96,6 +96,11 @@ public class PageDelegateIndex extends PageIndex {
...
@@ -96,6 +96,11 @@ public class PageDelegateIndex extends PageIndex {
return
-
1
;
return
-
1
;
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
getColumnIndex
(
column
)
==
0
;
}
@Override
@Override
public
double
getCost
(
Session
session
,
int
[]
masks
,
public
double
getCost
(
Session
session
,
int
[]
masks
,
TableFilter
[]
filters
,
int
filter
,
SortOrder
sortOrder
,
TableFilter
[]
filters
,
int
filter
,
SortOrder
sortOrder
,
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/ScanIndex.java
浏览文件 @
877c03fb
...
@@ -222,6 +222,11 @@ public class ScanIndex extends BaseIndex {
...
@@ -222,6 +222,11 @@ public class ScanIndex extends BaseIndex {
return
-
1
;
return
-
1
;
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
false
;
}
@Override
@Override
public
void
checkRename
()
{
public
void
checkRename
()
{
throw
DbException
.
getUnsupportedException
(
"SCAN"
);
throw
DbException
.
getUnsupportedException
(
"SCAN"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/MVDelegateIndex.java
浏览文件 @
877c03fb
...
@@ -88,6 +88,11 @@ public class MVDelegateIndex extends BaseIndex implements MVIndex {
...
@@ -88,6 +88,11 @@ public class MVDelegateIndex extends BaseIndex implements MVIndex {
return
-
1
;
return
-
1
;
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
getColumnIndex
(
column
)
==
0
;
}
@Override
@Override
public
double
getCost
(
Session
session
,
int
[]
masks
,
public
double
getCost
(
Session
session
,
int
[]
masks
,
TableFilter
[]
filters
,
int
filter
,
SortOrder
sortOrder
,
TableFilter
[]
filters
,
int
filter
,
SortOrder
sortOrder
,
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
浏览文件 @
877c03fb
...
@@ -242,6 +242,11 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -242,6 +242,11 @@ public class MVPrimaryIndex extends BaseIndex {
return
-
1
;
return
-
1
;
}
}
@Override
public
boolean
isFirstColumn
(
Column
column
)
{
return
false
;
}
@Override
@Override
public
void
remove
(
Session
session
)
{
public
void
remove
(
Session
session
)
{
TransactionMap
<
Value
,
Value
>
map
=
getMap
(
session
);
TransactionMap
<
Value
,
Value
>
map
=
getMap
(
session
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/Table.java
浏览文件 @
877c03fb
...
@@ -1050,22 +1050,34 @@ public abstract class Table extends SchemaObjectBase {
...
@@ -1050,22 +1050,34 @@ public abstract class Table extends SchemaObjectBase {
* This method returns null if no matching index is found.
* This method returns null if no matching index is found.
*
*
* @param column the column
* @param column the column
* @param needGetFirstOrLast if the returned index must be able
* to do {@link Index#canGetFirstOrLast()}
* @param needFindNext if the returned index must be able to do
* {@link Index#findNext(Session, SearchRow, SearchRow)}
* @return the index or null
* @return the index or null
*/
*/
public
Index
getIndexForColumn
(
Column
column
)
{
public
Index
getIndexForColumn
(
Column
column
,
boolean
needGetFirstOrLast
,
boolean
needFindNext
)
{
ArrayList
<
Index
>
indexes
=
getIndexes
();
ArrayList
<
Index
>
indexes
=
getIndexes
();
Index
result
=
null
;
if
(
indexes
!=
null
)
{
if
(
indexes
!=
null
)
{
for
(
int
i
=
1
,
size
=
indexes
.
size
();
i
<
size
;
i
++)
{
for
(
int
i
=
1
,
size
=
indexes
.
size
();
i
<
size
;
i
++)
{
Index
index
=
indexes
.
get
(
i
);
Index
index
=
indexes
.
get
(
i
);
if
(
index
.
canGetFirstOrLast
())
{
if
(
needGetFirstOrLast
&&
!
index
.
canGetFirstOrLast
())
{
int
idx
=
index
.
getColumnIndex
(
column
);
continue
;
if
(
idx
==
0
)
{
return
index
;
}
}
if
(
needFindNext
&&
!
index
.
canFindNext
())
{
continue
;
}
}
// choose the minimal covering index with the needed first column
// to work consistently with execution plan from Optimizer
if
(
index
.
isFirstColumn
(
column
)
&&
(
result
==
null
||
result
.
getColumns
().
length
>
index
.
getColumns
().
length
))
{
result
=
index
;
}
}
}
}
return
null
;
}
return
result
;
}
}
public
boolean
getOnCommitDrop
()
{
public
boolean
getOnCommitDrop
()
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestIndexHints.java
浏览文件 @
877c03fb
...
@@ -18,6 +18,8 @@ import java.sql.Statement;
...
@@ -18,6 +18,8 @@ import java.sql.Statement;
*/
*/
public
class
TestIndexHints
extends
TestBase
{
public
class
TestIndexHints
extends
TestBase
{
private
Connection
conn
;
/**
/**
* Run just this test.
* Run just this test.
*
*
...
@@ -39,11 +41,12 @@ public class TestIndexHints extends TestBase {
...
@@ -39,11 +41,12 @@ public class TestIndexHints extends TestBase {
testPlanSqlHasIndexesInCorrectOrder
();
testPlanSqlHasIndexesInCorrectOrder
();
testWithTableAlias
();
testWithTableAlias
();
testWithTableAliasCalledUse
();
testWithTableAliasCalledUse
();
conn
.
close
();
deleteDb
(
"indexhints"
);
deleteDb
(
"indexhints"
);
}
}
private
void
createDb
()
throws
SQLException
{
private
void
createDb
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table test (x int, y int)"
);
stat
.
execute
(
"create table test (x int, y int)"
);
stat
.
execute
(
"create index idx1 on test (x)"
);
stat
.
execute
(
"create index idx1 on test (x)"
);
...
@@ -52,7 +55,6 @@ public class TestIndexHints extends TestBase {
...
@@ -52,7 +55,6 @@ public class TestIndexHints extends TestBase {
}
}
private
void
testQuotedIdentifier
()
throws
SQLException
{
private
void
testQuotedIdentifier
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
"from test use index(\"Idx3\") where x=1 and y=1"
);
"from test use index(\"Idx3\") where x=1 and y=1"
);
...
@@ -66,54 +68,44 @@ public class TestIndexHints extends TestBase {
...
@@ -66,54 +68,44 @@ public class TestIndexHints extends TestBase {
plan
=
rs
.
getString
(
1
);
plan
=
rs
.
getString
(
1
);
assertTrue
(
plan
.
contains
(
"/* PUBLIC.\"Idx3\":"
));
assertTrue
(
plan
.
contains
(
"/* PUBLIC.\"Idx3\":"
));
assertTrue
(
plan
.
contains
(
"USE INDEX (\"Idx3\")"
));
assertTrue
(
plan
.
contains
(
"USE INDEX (\"Idx3\")"
));
conn
.
close
();
}
}
private
void
testWithSingleIndexName
()
throws
SQLException
{
private
void
testWithSingleIndexName
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
"from test use index(idx1) where x=1 and y=1"
);
"from test use index(idx1) where x=1 and y=1"
);
rs
.
next
();
rs
.
next
();
String
result
=
rs
.
getString
(
1
);
String
result
=
rs
.
getString
(
1
);
assertTrue
(
result
.
contains
(
"/* PUBLIC.IDX1:"
));
assertTrue
(
result
.
contains
(
"/* PUBLIC.IDX1:"
));
conn
.
close
();
}
}
private
void
testWithTableAlias
()
throws
SQLException
{
private
void
testWithTableAlias
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
"from test t use index(idx2) where x=1 and y=1"
);
"from test t use index(idx2) where x=1 and y=1"
);
rs
.
next
();
rs
.
next
();
String
result
=
rs
.
getString
(
1
);
String
result
=
rs
.
getString
(
1
);
assertTrue
(
result
.
contains
(
"/* PUBLIC.IDX2:"
));
assertTrue
(
result
.
contains
(
"/* PUBLIC.IDX2:"
));
conn
.
close
();
}
}
private
void
testWithTableAliasCalledUse
()
throws
SQLException
{
private
void
testWithTableAliasCalledUse
()
throws
SQLException
{
// make sure that while adding new syntax for table hints, code
// make sure that while adding new syntax for table hints, code
// that uses "USE" as a table alias still works
// that uses "USE" as a table alias still works
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
stat
.
executeQuery
(
"explain analyze select * "
+
stat
.
executeQuery
(
"explain analyze select * "
+
"from test use where use.x=1 and use.y=1"
);
"from test use where use.x=1 and use.y=1"
);
conn
.
close
();
}
}
private
void
testWithMultipleIndexNames
()
throws
SQLException
{
private
void
testWithMultipleIndexNames
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
"from test use index(idx1, idx2) where x=1 and y=1"
);
"from test use index(idx1, idx2) where x=1 and y=1"
);
rs
.
next
();
rs
.
next
();
String
result
=
rs
.
getString
(
1
);
String
result
=
rs
.
getString
(
1
);
assertTrue
(
result
.
contains
(
"/* PUBLIC.IDX2:"
));
assertTrue
(
result
.
contains
(
"/* PUBLIC.IDX2:"
));
conn
.
close
();
}
}
private
void
testPlanSqlHasIndexesInCorrectOrder
()
throws
SQLException
{
private
void
testPlanSqlHasIndexesInCorrectOrder
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
"explain analyze select * "
+
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
"explain analyze select * "
+
"from test use index(idx1, idx2) where x=1 and y=1"
);
"from test use index(idx1, idx2) where x=1 and y=1"
);
rs
.
next
();
rs
.
next
();
...
@@ -123,23 +115,18 @@ public class TestIndexHints extends TestBase {
...
@@ -123,23 +115,18 @@ public class TestIndexHints extends TestBase {
"from test use index(idx2, idx1) where x=1 and y=1"
);
"from test use index(idx2, idx1) where x=1 and y=1"
);
rs2
.
next
();
rs2
.
next
();
assertTrue
(
rs2
.
getString
(
1
).
contains
(
"USE INDEX (IDX2, IDX1)"
));
assertTrue
(
rs2
.
getString
(
1
).
contains
(
"USE INDEX (IDX2, IDX1)"
));
conn
.
close
();
}
}
private
void
testWithEmptyIndexHintsList
()
throws
SQLException
{
private
void
testWithEmptyIndexHintsList
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
ResultSet
rs
=
stat
.
executeQuery
(
"explain analyze select * "
+
"from test use index () where x=1 and y=1"
);
"from test use index () where x=1 and y=1"
);
rs
.
next
();
rs
.
next
();
String
result
=
rs
.
getString
(
1
);
String
result
=
rs
.
getString
(
1
);
assertTrue
(
result
.
contains
(
"/* PUBLIC.TEST.tableScan"
));
assertTrue
(
result
.
contains
(
"/* PUBLIC.TEST.tableScan"
));
conn
.
close
();
}
}
private
void
testWithInvalidIndexName
()
throws
SQLException
{
private
void
testWithInvalidIndexName
()
throws
SQLException
{
Connection
conn
=
getConnection
(
"indexhints"
);
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
try
{
try
{
stat
.
executeQuery
(
"explain analyze select * "
+
stat
.
executeQuery
(
"explain analyze select * "
+
...
@@ -148,8 +135,6 @@ public class TestIndexHints extends TestBase {
...
@@ -148,8 +135,6 @@ public class TestIndexHints extends TestBase {
+
"Index \"IDX_DOESNT_EXIST\" not found"
);
+
"Index \"IDX_DOESNT_EXIST\" not found"
);
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
assertEquals
(
ErrorCode
.
INDEX_NOT_FOUND_1
,
e
.
getErrorCode
());
assertEquals
(
ErrorCode
.
INDEX_NOT_FOUND_1
,
e
.
getErrorCode
());
}
finally
{
conn
.
close
();
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论