pgLab/queryexplainmodel.cpp

220 lines
4.8 KiB
C++
Raw Normal View History

#include "queryexplainmodel.h"
#include <QColor>
#include <QSize>
const int c_ColumnNode = 0;
const int c_ColumnExclusive = 1;
const int c_ColumnInclusive = 2;
const int c_ColumnEstErr = 3;
const int c_ColumnRowCount = 4;
const int c_ColumnLoops = 5;
const int c_ColumnDetails = 6;
const int c_NumberOfColumns = 7;
QueryExplainModel::QueryExplainModel(QObject *parent,
std::unique_ptr<ExplainRoot> exp)
: QAbstractItemModel(parent)
, explain(std::move(exp))
{}
QVariant QueryExplainModel::data(const QModelIndex &index, int role) const
{
QVariant result;
if (index.isValid()) {
int col = index.column();
ExplainTreeModelItem *item = static_cast<ExplainTreeModelItem*>(index.internalPointer());
if (role == Qt::DisplayRole) {
switch (col) {
case c_ColumnNode:
result = item->nodeType();
break;
case c_ColumnExclusive:
result = item->exclusiveTime();
break;
case c_ColumnInclusive:
result = item->inclusiveTime();
break;
case c_ColumnEstErr:
result = item->estimateError();
break;
case c_ColumnRowCount:
result = item->actualRows();
break;
case c_ColumnLoops:
result = item->actualLoops();
break;
case c_ColumnDetails:
result = item->detailString();
break;
} // end switch column
}
else if (role == Qt::TextAlignmentRole) {
if (col == c_ColumnNode || col == c_ColumnDetails) {
result = Qt::AlignLeft + Qt::AlignVCenter;
}
else {
result = Qt::AlignRight + Qt::AlignVCenter;
}
}
else if (role == Qt::BackgroundColorRole) {
if (col == c_ColumnExclusive || col == c_ColumnInclusive) {
float t = col == 1 ? item->exclusiveTime() : item->inclusiveTime();
float tt = explain->plan->inclusiveTime();
if (tt > 0.000000001) {
float f = t / tt;
if (f > 0.9) {
result = QColor(255, 192, 192);
}
else if (f > 0.63) {
result = QColor(255, 224, 192);
}
else if (f > 0.36f) {
result = QColor(255, 255, 192);
}
else if (f > 0.09f) {
result = QColor(255, 255, 224);
}
else {
result = QColor(Qt::white);
}
}
}
if (col == c_ColumnEstErr) {
float e = fabs(item->estimateError());
if (e > 1000.0f) {
result = QColor(255, 192, 192);
}
else if (e > 100.0f) {
result = QColor(255, 224, 192);
}
else if (e > 10.0f) {
result = QColor(255, 255, 192);
}
else {
result = QColor(Qt::white);
}
}
}
}
return result;
}
//Qt::ItemFlags QueryExplainModel::flags(const QModelIndex &index) const
//{
//}
QVariant QueryExplainModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
QVariant v;
if (orientation == Qt::Horizontal) {
if (role == Qt::DisplayRole ) {
switch (section) {
case c_ColumnNode:
v = "Node";
break;
case c_ColumnExclusive:
v = "Exclusive";
break;
case c_ColumnInclusive:
v = "Inclusive";
break;
case c_ColumnEstErr:
v = "Est. Err";
break;
case c_ColumnRowCount:
v = "Rows";
break;
case c_ColumnLoops:
v = "Loops";
break;
case c_ColumnDetails:
v = "Details";
break;
}
}
// else if (role == Qt::SizeHintRole) {
// switch (section) {
// case 0:
// v = QSize();
// break;
// case 1:
// v = "Exclusive";
// break;
// case 2:
// v = "Inclusive";
// break;
// case 3:
// v = "Est. Err";
// break;
// }
// }
}
return v;
}
QModelIndex QueryExplainModel::index(int row, int column,
const QModelIndex &parent) const
{
QModelIndex result;
if (hasIndex(row, column, parent)) {
if (parent.isValid()) {
ExplainTreeModelItem *parentItem =
static_cast<ExplainTreeModelItem*>(parent.internalPointer());
if (parentItem) {
ExplainTreeModelItemPtr childItem = parentItem->child(row);
if (childItem) {
result = createIndex(row, column, childItem.get());
}
}
}
else {
result = createIndex(row, column, explain->plan.get());
}
}
return result;
}
QModelIndex QueryExplainModel::parent(const QModelIndex &index) const
{
QModelIndex result;
if (index.isValid()) {
ExplainTreeModelItem *childItem = static_cast<ExplainTreeModelItem*>(index.internalPointer());
auto parentItem = childItem->parent();
if (parentItem != nullptr) {
result = createIndex( parentItem->row(), 0, parentItem.get());
}
}
return result;
}
int QueryExplainModel::rowCount(const QModelIndex &parent) const
{
int result = 0;
if (parent.column() <= 0) {
if (parent.isValid()) {
auto item = static_cast<ExplainTreeModelItem*>(parent.internalPointer());
result = item->childCount();
}
else {
result = 1;
}
}
return result;
}
int QueryExplainModel::columnCount(const QModelIndex &parent) const
{
// if (parent.isValid()) {
// return 6;//static_cast<ExplainTreeModelItem*>(parent.internalPointer())->columnCount();
// }
// else {
// return 1;
// }
return c_NumberOfColumns;
}