Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
suliangchun
dbeaver
提交
d7b4e57a
D
dbeaver
项目概览
suliangchun
/
dbeaver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dbeaver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d7b4e57a
编写于
2月 19, 2019
作者:
S
Serge Rider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MySQL plan json format support
上级
2bbefc22
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
233 addition
and
221 deletion
+233
-221
plugins/org.jkiss.dbeaver.ext.mysql/META-INF/MANIFEST.MF
plugins/org.jkiss.dbeaver.ext.mysql/META-INF/MANIFEST.MF
+2
-1
plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/plan/MySQLPlanJSON.java
...org/jkiss/dbeaver/ext/mysql/model/plan/MySQLPlanJSON.java
+48
-5
plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/plan/MySQLPlanNodeJSON.java
...jkiss/dbeaver/ext/mysql/model/plan/MySQLPlanNodeJSON.java
+129
-165
plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/plan/PostgrePlanNode.java
...ss/dbeaver/ext/postgresql/model/plan/PostgrePlanNode.java
+54
-50
未找到文件。
plugins/org.jkiss.dbeaver.ext.mysql/META-INF/MANIFEST.MF
浏览文件 @
d7b4e57a
...
...
@@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ui.editors,
org.jkiss.dbeaver.model,
org.jkiss.dbeaver.core,
org.jkiss.dbeaver.data.gis
org.jkiss.dbeaver.data.gis,
com.google.gson
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: JKISS
...
...
plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/plan/MySQLPlanJSON.java
浏览文件 @
d7b4e57a
...
...
@@ -16,6 +16,10 @@
*/
package
org.jkiss.dbeaver.ext.mysql.model.plan
;
import
com.google.gson.Gson
;
import
com.google.gson.JsonElement
;
import
com.google.gson.JsonObject
;
import
com.google.gson.JsonPrimitive
;
import
org.jkiss.dbeaver.ext.mysql.model.MySQLDataSource
;
import
org.jkiss.dbeaver.model.exec.DBCException
;
import
org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement
;
...
...
@@ -23,17 +27,26 @@ import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet;
import
org.jkiss.dbeaver.model.exec.jdbc.JDBCSession
;
import
org.jkiss.dbeaver.model.exec.plan.DBCPlanCostNode
;
import
org.jkiss.dbeaver.model.sql.SQLUtils
;
import
org.jkiss.utils.CommonUtils
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* MySQL JSON plan
*/
public
class
MySQLPlanJSON
extends
MySQLPlanAbstract
{
private
final
String
[]
nodePropNames
=
new
String
[]
{
"ordering_operation"
,
"grouping_operation"
,
"nested_loop"
,
"table"
,
"attached_subqueries"
,
"optimized_away_subqueries"
,
"materialized_from_subquery"
,
"duplicates_removal"
};
private
static
final
Gson
gson
=
new
Gson
();
private
List
<
MySQLPlanNodeJSON
>
rootNodes
;
public
MySQLPlanJSON
(
JDBCSession
session
,
String
query
)
throws
DBCException
{
...
...
@@ -47,10 +60,39 @@ public class MySQLPlanJSON extends MySQLPlanAbstract {
try
(
JDBCResultSet
dbResult
=
dbStat
.
executeQuery
())
{
List
<
MySQLPlanNodeJSON
>
nodes
=
new
ArrayList
<>();
while
(
dbResult
.
next
())
{
// MySQLPlanNodePlain node = new MySQLPlanNodePlain(null, dbResult);
// nodes.add(node);
dbResult
.
next
();
String
jsonPlan
=
dbResult
.
getString
(
1
);
JsonObject
planObject
=
gson
.
fromJson
(
jsonPlan
,
JsonObject
.
class
);
JsonObject
queryBlock
=
planObject
.
getAsJsonObject
(
"query_block"
);
MySQLPlanNodeJSON
rootNode
=
new
MySQLPlanNodeJSON
(
null
,
"select"
,
queryBlock
);
/*
for (Map.Entry<String, JsonElement> prop : queryBlock.entrySet()) {
JsonElement value = prop.getValue();
switch (prop.getKey()) {
case "select_id":
selectId = value.getAsLong();
break;
case "query_cost":
break;
case "message":
errorMessage = value.getAsString();
break;
default:
if (value instanceof JsonObject) {
MySQLPlanNodeJSON nodeJSON = new MySQLPlanNodeJSON(null, prop.getKey(), (JsonObject) value);
nodes.add(nodeJSON);
} else if (value instanceof JsonObject) {
}
}
}
*/
if
(
CommonUtils
.
isEmpty
(
rootNode
.
getNested
())
&&
rootNode
.
getProperty
(
"message"
)
!=
null
)
{
throw
new
DBCException
(
"Can't explain plan: "
+
rootNode
.
getProperty
(
"message"
));
}
nodes
.
add
(
rootNode
);
rootNodes
=
nodes
;
}
...
...
@@ -61,7 +103,8 @@ public class MySQLPlanJSON extends MySQLPlanAbstract {
@Override
public
Object
getPlanFeature
(
String
feature
)
{
if
(
DBCPlanCostNode
.
FEATURE_PLAN_ROWS
.
equals
(
feature
))
{
if
(
DBCPlanCostNode
.
FEATURE_PLAN_COST
.
equals
(
feature
)
||
DBCPlanCostNode
.
FEATURE_PLAN_ROWS
.
equals
(
feature
))
{
return
true
;
}
return
super
.
getPlanFeature
(
feature
);
...
...
@@ -74,7 +117,7 @@ public class MySQLPlanJSON extends MySQLPlanAbstract {
@Override
public
String
getPlanQueryString
()
{
return
"EXPLAIN
EXTENDED
"
+
query
;
return
"EXPLAIN
FORMAT=JSON
"
+
query
;
}
@Override
...
...
plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/plan/MySQLPlanNodeJSON.java
浏览文件 @
d7b4e57a
...
...
@@ -16,14 +16,18 @@
*/
package
org.jkiss.dbeaver.ext.mysql.model.plan
;
import
org.jkiss.dbeaver.model.exec.plan.DBCPlanNodeKind
;
import
org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils
;
import
com.google.gson.JsonArray
;
import
com.google.gson.JsonElement
;
import
com.google.gson.JsonObject
;
import
org.jkiss.code.Nullable
;
import
org.jkiss.dbeaver.model.impl.PropertyDescriptor
;
import
org.jkiss.dbeaver.model.meta.Property
;
import
org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor
;
import
org.jkiss.dbeaver.model.preferences.DBPPropertySource
;
import
org.jkiss.dbeaver.model.runtime.DBRProgressMonitor
;
import
org.jkiss.utils.CommonUtils
;
import
java.sql.ResultSet
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.*
;
/**
* MySQL execution plan node based on JSON format
...
...
@@ -41,228 +45,188 @@ import java.util.List;
UNION RESULT – the SELECT is a result of a UNION
*/
public
class
MySQLPlanNodeJSON
extends
MySQLPlanNode
{
protected
Integer
id
;
protected
String
selectType
;
protected
String
table
;
protected
String
type
;
protected
String
possibleKeys
;
protected
String
key
;
protected
String
keyLength
;
protected
String
ref
;
protected
Long
rowCount
;
protected
Long
filtered
;
protected
String
extra
;
protected
MySQLPlanNodeJSON
parent
;
protected
List
<
MySQLPlanNodeJSON
>
nested
;
public
MySQLPlanNodeJSON
(
List
<
MySQLPlanNodeJSON
>
nodes
)
{
// Root node
type
=
"<plan>"
;
if
(!
nodes
.
isEmpty
())
{
this
.
rowCount
=
nodes
.
get
(
0
).
rowCount
;
}
this
.
nested
=
nodes
;
}
public
class
MySQLPlanNodeJSON
extends
MySQLPlanNode
implements
DBPPropertySource
{
public
MySQLPlanNodeJSON
(
MySQLPlanNodeJSON
parent
,
ResultSet
dbResult
)
{
this
.
parent
=
parent
;
this
.
id
=
JDBCUtils
.
safeGetInteger
(
dbResult
,
"id"
);
this
.
selectType
=
JDBCUtils
.
safeGetString
(
dbResult
,
"select_type"
);
this
.
table
=
JDBCUtils
.
safeGetString
(
dbResult
,
"table"
);
this
.
type
=
JDBCUtils
.
safeGetString
(
dbResult
,
"type"
);
this
.
possibleKeys
=
JDBCUtils
.
safeGetString
(
dbResult
,
"possible_keys"
);
this
.
key
=
JDBCUtils
.
safeGetString
(
dbResult
,
"key"
);
this
.
keyLength
=
JDBCUtils
.
safeGetString
(
dbResult
,
"key_len"
);
this
.
ref
=
JDBCUtils
.
safeGetString
(
dbResult
,
"ref"
);
this
.
rowCount
=
JDBCUtils
.
safeGetLongNullable
(
dbResult
,
"rows"
);
this
.
filtered
=
JDBCUtils
.
safeGetLongNullable
(
dbResult
,
"filtered"
);
this
.
extra
=
JDBCUtils
.
safeGetString
(
dbResult
,
"extra"
);
}
private
MySQLPlanNodeJSON
parent
;
private
String
name
;
private
JsonObject
object
;
private
Map
<
String
,
Object
>
nodeProps
=
new
LinkedHashMap
<>();
private
JsonObject
costInfo
;
private
List
<
MySQLPlanNodeJSON
>
nested
;
public
MySQLPlanNodeJSON
(
MySQLPlanNodeJSON
parent
,
String
type
)
{
public
MySQLPlanNodeJSON
(
MySQLPlanNodeJSON
parent
,
String
name
,
JsonObject
object
)
{
this
.
parent
=
parent
;
this
.
selectType
=
type
;
}
protected
MySQLPlanNodeJSON
(
MySQLPlanNodeJSON
parent
,
MySQLPlanNodeJSON
source
)
{
this
.
id
=
source
.
id
;
this
.
selectType
=
source
.
selectType
;
this
.
table
=
source
.
table
;
this
.
type
=
source
.
type
;
this
.
possibleKeys
=
source
.
possibleKeys
;
this
.
key
=
source
.
key
;
this
.
keyLength
=
source
.
keyLength
;
this
.
ref
=
source
.
ref
;
this
.
rowCount
=
source
.
rowCount
;
this
.
filtered
=
source
.
filtered
;
this
.
extra
=
source
.
extra
;
this
.
parent
=
parent
;
if
(
source
.
nested
!=
null
)
{
this
.
nested
=
new
ArrayList
<>(
source
.
nested
.
size
());
for
(
MySQLPlanNodeJSON
srcNode
:
source
.
nested
)
{
this
.
nested
.
add
(
srcNode
.
copyNode
(
this
));
this
.
name
=
name
;
this
.
object
=
object
;
for
(
Map
.
Entry
<
String
,
JsonElement
>
prop
:
object
.
entrySet
())
{
String
propName
=
prop
.
getKey
();
JsonElement
value
=
prop
.
getValue
();
if
(
value
instanceof
JsonObject
)
{
if
(
"cost_info"
.
equals
(
propName
))
{
costInfo
=
(
JsonObject
)
value
;
}
else
{
addNested
(
propName
,
(
JsonObject
)
value
);
}
}
else
if
(
value
instanceof
JsonArray
)
{
boolean
isProp
=
false
;
int
itemIndex
=
0
;
for
(
JsonElement
item
:
(
JsonArray
)
value
)
{
if
(
item
instanceof
JsonObject
)
{
itemIndex
++;
addNested
(
propName
+
"#"
+
itemIndex
,
(
JsonObject
)
item
);
}
else
{
isProp
=
true
;
break
;
}
}
if
(
isProp
)
{
nodeProps
.
put
(
propName
,
value
.
toString
());
}
}
else
{
nodeProps
.
put
(
propName
,
value
.
getAsString
());
}
}
}
@Override
public
MySQLPlanNodeJSON
getParent
()
{
return
parent
;
}
void
setParent
(
MySQLPlanNodeJSON
node
)
{
if
(
this
.
parent
!=
null
&&
this
.
parent
.
nested
!=
null
)
{
this
.
parent
.
nested
.
remove
(
this
);
}
this
.
parent
=
node
;
if
(
this
.
parent
!=
null
)
{
this
.
parent
.
addChild
(
this
);
private
void
addNested
(
String
name
,
JsonObject
value
)
{
if
(
nested
==
null
)
{
nested
=
new
ArrayList
<>();
}
nested
.
add
(
new
MySQLPlanNodeJSON
(
this
,
name
,
value
)
);
}
private
void
addChild
(
MySQLPlanNodeJSON
node
)
{
if
(
this
.
nested
==
null
)
{
this
.
nested
=
new
ArrayList
<>();
}
this
.
nested
.
add
(
node
);
@Override
public
String
getNodeName
()
{
Object
nodeName
=
nodeProps
.
get
(
"table_name"
);
if
(
nodeName
==
null
)
{
}
return
nodeName
==
null
?
null
:
String
.
valueOf
(
nodeName
);
}
@Property
(
order
=
0
,
viewable
=
true
)
@Override
public
String
getNode
Nam
e
()
{
return
tabl
e
;
public
String
getNode
Typ
e
()
{
return
nam
e
;
}
@Override
public
DBCPlanNodeKind
getNodeKind
()
{
if
(
"SIMPLE"
.
equals
(
selectType
)
)
{
return
DBCPlanNodeKind
.
SELECT
;
}
else
if
(
"JOIN"
.
equals
(
selectType
))
{
return
DBCPlanNodeKind
.
JOIN
;
}
else
if
(
"UNION"
.
equals
(
selectType
)
)
{
re
turn
DBCPlanNodeKind
.
UNION
;
public
Number
getNodeCost
()
{
if
(
costInfo
==
null
)
{
return
null
;
}
JsonElement
readCost
=
costInfo
.
get
(
"read_cost"
)
;
if
(
readCost
==
null
)
{
re
adCost
=
costInfo
.
get
(
"query_cost"
)
;
}
return
super
.
getNodeKind
();
if
(
readCost
==
null
)
{
return
null
;
}
return
readCost
.
getAsDouble
();
}
@Override
public
String
getNodeDescription
()
{
return
ref
;
public
Number
getNodePercent
()
{
return
null
;
}
@Override
@Property
(
order
=
3
,
viewable
=
true
)
public
String
getNodeType
()
{
return
selectType
;
public
Number
getNodeDuration
()
{
return
null
;
}
@Override
public
List
<
MySQLPlanNodeJSON
>
getNested
()
{
return
nested
;
}
@Property
(
order
=
0
,
viewable
=
true
)
public
Integer
getId
()
{
return
id
;
}
public
Number
getNodeRowCount
()
{
Object
rowCount
=
nodeProps
.
get
(
"rows_examined_per_scan"
);
if
(
rowCount
==
null
)
{
@Property
(
order
=
1
,
viewable
=
true
)
public
String
getSelectType
()
{
return
selectType
;
}
return
rowCount
==
null
?
null
:
CommonUtils
.
toLong
(
rowCount
);
}
@
Property
(
order
=
2
,
viewable
=
true
)
public
String
getTable
()
{
return
table
;
@
Override
public
MySQLPlanNodeJSON
getParent
()
{
return
parent
;
}
@
Property
(
order
=
4
,
viewable
=
true
)
public
String
getPossibleKeys
()
{
return
possibleKeys
;
@
Override
public
Collection
<
MySQLPlanNodeJSON
>
getNested
()
{
return
nested
;
}
@Property
(
order
=
5
,
viewable
=
true
)
public
String
getKey
()
{
return
key
;
public
Object
getProperty
(
String
name
)
{
return
nodeProps
.
get
(
name
);
}
@
Property
(
order
=
6
,
viewable
=
true
)
public
String
getKeyLength
()
{
return
keyLength
;
@
Override
public
String
toString
()
{
return
object
.
toString
()
;
}
@Property
(
order
=
7
,
viewable
=
true
)
public
String
getRef
()
{
return
ref
;
}
//////////////////////////////////////////////////////////
// Properties
@
Property
(
order
=
8
,
viewable
=
true
)
public
Long
getRowCount
()
{
return
rowCount
;
@
Override
public
Object
getEditableValue
()
{
return
this
;
}
@Property
(
order
=
9
,
viewable
=
true
)
public
Long
getFiltered
()
{
return
filtered
;
@Override
public
DBPPropertyDescriptor
[]
getPropertyDescriptors2
()
{
DBPPropertyDescriptor
[]
props
=
new
DBPPropertyDescriptor
[
nodeProps
.
size
()];
int
index
=
0
;
for
(
Map
.
Entry
<
String
,
Object
>
attr
:
nodeProps
.
entrySet
())
{
props
[
index
++]
=
new
PropertyDescriptor
(
"Source"
,
attr
.
getKey
(),
attr
.
getKey
(),
null
,
String
.
class
,
false
,
null
,
null
,
false
);
}
return
props
;
}
@
Property
(
order
=
10
,
viewable
=
true
)
public
String
getExtra
(
)
{
return
extra
;
@
Override
public
Object
getPropertyValue
(
@Nullable
DBRProgressMonitor
monitor
,
Object
id
)
{
return
nodeProps
.
get
(
id
.
toString
())
;
}
@Override
public
Number
getNodeCost
(
)
{
return
null
;
public
boolean
isPropertySet
(
Object
id
)
{
return
false
;
//attributes.containsKey(id.toString())
;
}
@Override
public
Number
getNodePercent
(
)
{
return
null
;
public
boolean
isPropertyResettable
(
Object
id
)
{
return
false
;
}
@Override
public
Number
getNodeDuration
(
)
{
return
null
;
public
void
resetPropertyValue
(
@Nullable
DBRProgressMonitor
monitor
,
Object
id
)
{
}
@Override
public
Number
getNodeRowCount
()
{
return
rowCount
;
}
public
void
resetPropertyValueToDefault
(
Object
id
)
{
public
boolean
isCompositeNode
()
{
return
"PRIMARY"
.
equals
(
selectType
);
}
@Override
public
String
toString
()
{
return
id
+
" "
+
selectType
+
" "
+
table
;
}
public
void
setPropertyValue
(
@Nullable
DBRProgressMonitor
monitor
,
Object
id
,
Object
value
)
{
void
computeStats
()
{
if
(
nested
!=
null
)
{
for
(
MySQLPlanNodeJSON
child
:
nested
)
{
child
.
computeStats
();
}
}
if
(
rowCount
==
null
)
{
if
(
nested
!=
null
)
{
long
calcCount
=
0
;
for
(
MySQLPlanNodeJSON
child
:
nested
)
{
child
.
computeStats
();
calcCount
+=
CommonUtils
.
toLong
(
child
.
getRowCount
());
}
this
.
rowCount
=
calcCount
;
}
}
}
MySQLPlanNodeJSON
copyNode
(
MySQLPlanNodeJSON
parent
)
{
return
new
MySQLPlanNodeJSON
(
parent
,
this
);
@Override
public
boolean
isDirty
(
Object
id
)
{
return
false
;
}
}
plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/plan/PostgrePlanNode.java
浏览文件 @
d7b4e57a
...
...
@@ -169,6 +169,51 @@ public class PostgrePlanNode extends AbstractExecutionPlanNode implements DBCPla
return
nested
;
}
@Override
public
Number
getNodeCost
()
{
String
totalCost
=
attributes
.
get
(
ATTR_TOTAL_COST
);
return
totalCost
==
null
?
null
:
CommonUtils
.
toDouble
(
totalCost
);
}
@Override
public
Number
getNodePercent
()
{
return
null
;
// String costPercent = attributes.get(ATTR_TOTAL_COST);
// return costPercent == null ? null : CommonUtils.toDouble(costPercent);
}
@Override
public
Number
getNodeDuration
()
{
String
time
=
attributes
.
get
(
ATTR_ACTUAL_TOTAL_TIME
);
return
time
==
null
?
null
:
CommonUtils
.
toDouble
(
time
);
}
@Override
public
Number
getNodeRowCount
()
{
String
rows
=
attributes
.
get
(
ATTR_ACTUAL_ROWS
);
return
rows
==
null
?
null
:
CommonUtils
.
toLong
(
rows
);
}
@Override
public
String
toString
()
{
StringBuilder
title
=
new
StringBuilder
();
title
.
append
(
"Type: "
).
append
(
nodeType
);
String
joinType
=
attributes
.
get
(
"Join-Type"
);
if
(!
CommonUtils
.
isEmpty
(
joinType
))
{
title
.
append
(
" ("
).
append
(
joinType
).
append
(
")"
);
}
title
.
append
(
"; "
);
if
(!
CommonUtils
.
isEmpty
(
entity
))
{
title
.
append
(
"Rel: "
).
append
(
entity
).
append
(
" "
);
}
title
.
append
(
"; Cost: "
).
append
(
cost
);
return
title
.
toString
();
}
//////////////////////////////////////////////////////////
// Properties
@Override
public
Object
getEditableValue
()
{
return
this
;
...
...
@@ -180,15 +225,15 @@ public class PostgrePlanNode extends AbstractExecutionPlanNode implements DBCPla
int
index
=
0
;
for
(
Map
.
Entry
<
String
,
String
>
attr
:
attributes
.
entrySet
())
{
props
[
index
++]
=
new
PropertyDescriptor
(
"Source"
,
attr
.
getKey
(),
attr
.
getKey
(),
null
,
String
.
class
,
false
,
null
,
null
,
false
);
"Source"
,
attr
.
getKey
(),
attr
.
getKey
(),
null
,
String
.
class
,
false
,
null
,
null
,
false
);
}
return
props
;
}
...
...
@@ -228,45 +273,4 @@ public class PostgrePlanNode extends AbstractExecutionPlanNode implements DBCPla
return
false
;
}
@Override
public
String
toString
()
{
StringBuilder
title
=
new
StringBuilder
();
title
.
append
(
"Type: "
).
append
(
nodeType
);
String
joinType
=
attributes
.
get
(
"Join-Type"
);
if
(!
CommonUtils
.
isEmpty
(
joinType
))
{
title
.
append
(
" ("
).
append
(
joinType
).
append
(
")"
);
}
title
.
append
(
"; "
);
if
(!
CommonUtils
.
isEmpty
(
entity
))
{
title
.
append
(
"Rel: "
).
append
(
entity
).
append
(
" "
);
}
title
.
append
(
"; Cost: "
).
append
(
cost
);
return
title
.
toString
();
}
@Override
public
Number
getNodeCost
()
{
String
totalCost
=
attributes
.
get
(
ATTR_TOTAL_COST
);
return
totalCost
==
null
?
null
:
CommonUtils
.
toDouble
(
totalCost
);
}
@Override
public
Number
getNodePercent
()
{
return
null
;
// String costPercent = attributes.get(ATTR_TOTAL_COST);
// return costPercent == null ? null : CommonUtils.toDouble(costPercent);
}
@Override
public
Number
getNodeDuration
()
{
String
time
=
attributes
.
get
(
ATTR_ACTUAL_TOTAL_TIME
);
return
time
==
null
?
null
:
CommonUtils
.
toDouble
(
time
);
}
@Override
public
Number
getNodeRowCount
()
{
String
rows
=
attributes
.
get
(
ATTR_ACTUAL_ROWS
);
return
rows
==
null
?
null
:
CommonUtils
.
toLong
(
rows
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录