#include "QueryExplainModel.h" #include #include #include 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_ColumnShared = 7; const int c_NumberOfColumns = 8; QueryExplainModel::QueryExplainModel(QObject *parent, ExplainRoot::SPtr exp) : QAbstractItemModel(parent) , explain(std::move(exp)) , theme(GetColorTheme()) {} QVariant QueryExplainModel::data(const QModelIndex &index, int role) const { QVariant result; if (index.isValid()) { int col = index.column(); ExplainTreeModelItem *item = static_cast(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; case c_ColumnShared: result = item->sharedBlocks.asString(); break; } // end switch column } else if (role == Qt::TextAlignmentRole) { if (col == c_ColumnNode || col == c_ColumnDetails) { result = int(Qt::AlignLeft | Qt::AlignVCenter); } else { result = int(Qt::AlignRight | Qt::AlignVCenter); } } else if (role == Qt::BackgroundRole) { if (col == c_ColumnExclusive || col == c_ColumnInclusive) { float t = col == 1 ? item->exclusiveTime() : item->inclusiveTime(); float tt = explain->plan->inclusiveTime(); if (tt > 0.000000001f) { float f = t / tt; if (f > 0.9f) { result = theme.explainTime[0]; } else if (f > 0.63f) { result = theme.explainTime[1]; } else if (f > 0.36f) { result = theme.explainTime[2]; } else if (f > 0.09f) { result = theme.explainTime[3]; } else { result = {}; } } } if (col == c_ColumnEstErr) { float e = std::fabs(item->estimateError()); if (e > 1000.0f) { result = theme.explainEstError[0]; } else if (e > 100.0f) { result = theme.explainEstError[1]; } else if (e > 10.0f) { result = theme.explainEstError[2]; } 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; case c_ColumnShared: v = "Shared"; 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(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(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(parent.internalPointer()); result = item->childCount(); } else { result = 1; } } return result; } int QueryExplainModel::columnCount(const QModelIndex &) const { // if (parent.isValid()) { // return 6;//static_cast(parent.internalPointer())->columnCount(); // } // else { // return 1; // } return c_NumberOfColumns; }