@@ -587,6 +587,7 @@ public:
587587 KeepTranParams = true;
588588 TranParams->assign(DEFAULT_DML_TRANS_SQL);
589589 PerTableStats = false;
590+ WireStats = false;
590591 }
591592
592593 ColList global_Cols;
@@ -611,6 +612,7 @@ public:
611612 SCHAR ISQL_charset[MAXCHARSET_SIZE];
612613 bool KeepTranParams;
613614 bool PerTableStats;
615+ bool WireStats;
614616};
615617
616618static SetValues setValues;
@@ -5381,7 +5383,7 @@ static processing_state frontend_set(const char* cmd, const char* const* parms,
53815383 exec_path_display,
53825384 sql, warning, sqlCont, heading, bail,
53835385 bulk_insert, maxrows, stmtTimeout,
5384- keepTranParams, perTableStats,
5386+ keepTranParams, perTableStats, wireStats,
53855387 wrong
53865388 };
53875389 SetOptions(const optionsMap* inmap, size_t insize, int wrongval)
@@ -5422,7 +5424,8 @@ static processing_state frontend_set(const char* cmd, const char* const* parms,
54225424 {SetOptions::stmtTimeout, "LOCAL_TIMEOUT", 0},
54235425 {SetOptions::sqlCont, "DECFLOAT", 0},
54245426 {SetOptions::keepTranParams, "KEEP_TRAN_PARAMS", 9},
5425- {SetOptions::perTableStats, "PER_TABLE_STATS", 7}
5427+ {SetOptions::perTableStats, "PER_TABLE_STATS", 7},
5428+ {SetOptions::wireStats, "WIRE_STATS", 4}
54265429 };
54275430
54285431 // Display current set options
@@ -5662,6 +5665,10 @@ static processing_state frontend_set(const char* cmd, const char* const* parms,
56625665 ret = do_set_command(parms[2], &setValues.PerTableStats);
56635666 break;
56645667
5668+ case SetOptions::wireStats:
5669+ ret = do_set_command(parms[2], &setValues.WireStats);
5670+ break;
5671+
56655672 default:
56665673 //{
56675674 // TEXT msg_string[MSG_LENGTH];
@@ -6452,6 +6459,7 @@ static processing_state print_sets()
64526459
64536460 print_set("Print statistics:", setValues.Stats);
64546461 print_set("Print per-table stats:", setValues.PerTableStats);
6462+ print_set("Print wire stats:", setValues.WireStats);
64556463 print_set("Echo commands:", setValues.Echo);
64566464 print_set("List format:", setValues.List);
64576465 print_set("Show Row Count:", setValues.Docount);
@@ -9004,6 +9012,10 @@ static processing_state process_statement(const TEXT* str2)
90049012 if (setValues.PerTableStats)
90059013 perTableStats->getStats(DB, true);
90069014
9015+ IsqlWireStats wireStats(DB);
9016+ if (setValues.WireStats)
9017+ wireStats.get(true);
9018+
90079019 // Prepare the dynamic query stored in string.
90089020 // But put this on the DDL transaction to get maximum visibility of
90099021 // metadata.
@@ -9172,6 +9184,9 @@ static processing_state process_statement(const TEXT* str2)
91729184 if (setValues.PerTableStats)
91739185 perTableStats->getStats(DB, false);
91749186
9187+ if (setValues.WireStats)
9188+ wireStats.print(false);
9189+
91759190 return ret;
91769191 }
91779192
@@ -9191,6 +9206,9 @@ static processing_state process_statement(const TEXT* str2)
91919206 if (setValues.PerTableStats)
91929207 perTableStats->getStats(DB, false);
91939208
9209+ if (setValues.WireStats)
9210+ wireStats.print(false);
9211+
91949212 return ret;
91959213 }
91969214
@@ -9238,6 +9256,9 @@ static processing_state process_statement(const TEXT* str2)
92389256 if (setValues.PerTableStats)
92399257 perTableStats->getStats(DB, false);
92409258
9259+ if (setValues.WireStats)
9260+ wireStats.print(false);
9261+
92419262 return ret;
92429263 }
92439264
@@ -9433,6 +9454,9 @@ static processing_state process_statement(const TEXT* str2)
94339454 if (setValues.PerTableStats)
94349455 perTableStats->getStats(DB, false);
94359456
9457+ if (setValues.WireStats)
9458+ wireStats.print(false);
9459+
94369460 if (pad)
94379461 ISQL_FREE(pad);
94389462 if (line)
@@ -9930,3 +9954,126 @@ unsigned PerTableStats::loadRelNames(Firebird::IAttachment* att)
99309954
99319955 return maxLen;
99329956}
9957+
9958+ /// class IsqlWireStats
9959+
9960+ IsqlWireStats::IsqlWireStats(Firebird::IAttachment* att) :
9961+ m_att(att),
9962+ m_snd_packets(0),
9963+ m_rcv_packets(0),
9964+ m_out_packets(0),
9965+ m_in_packets(0),
9966+ m_snd_bytes(0),
9967+ m_rcv_bytes(0),
9968+ m_out_bytes(0),
9969+ m_in_bytes(0),
9970+ m_roundtrips(0)
9971+ {
9972+ }
9973+
9974+ bool IsqlWireStats::get(bool initial)
9975+ {
9976+ if (!m_att)
9977+ return false;
9978+
9979+ const UCHAR info[] = {
9980+ fb_info_wire_snd_packets, fb_info_wire_rcv_packets,
9981+ fb_info_wire_out_packets, fb_info_wire_in_packets,
9982+ fb_info_wire_snd_bytes, fb_info_wire_rcv_bytes,
9983+ fb_info_wire_out_bytes, fb_info_wire_in_bytes,
9984+ fb_info_wire_roundtrips,
9985+ isc_info_end
9986+ };
9987+
9988+ UCHAR buffer[128];
9989+
9990+ m_att->getInfo(fbStatus, sizeof(info), info, sizeof(buffer), buffer);
9991+
9992+ if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
9993+ return false;
9994+
9995+ Firebird::ClumpletReader p(Firebird::ClumpletReader::InfoResponse, buffer, sizeof(buffer));
9996+ for (; !p.isEof(); p.moveNext())
9997+ {
9998+ FB_UINT64* pField = nullptr;
9999+ switch (p.getClumpTag())
10000+ {
10001+ case fb_info_wire_snd_packets:
10002+ pField = &m_snd_packets;
10003+ break;
10004+ case fb_info_wire_rcv_packets:
10005+ pField = &m_rcv_packets;
10006+ break;
10007+ case fb_info_wire_out_packets:
10008+ pField = &m_out_packets;
10009+ break;
10010+ case fb_info_wire_in_packets:
10011+ pField = &m_in_packets;
10012+ break;
10013+ case fb_info_wire_snd_bytes:
10014+ pField = &m_snd_bytes;
10015+ break;
10016+ case fb_info_wire_rcv_bytes:
10017+ pField = &m_rcv_bytes;
10018+ break;
10019+ case fb_info_wire_out_bytes:
10020+ pField = &m_out_bytes;
10021+ break;
10022+ case fb_info_wire_in_bytes:
10023+ pField = &m_in_bytes;
10024+ break;
10025+ case fb_info_wire_roundtrips:
10026+ pField = &m_roundtrips;
10027+ break;
10028+ case isc_info_end:
10029+ break;
10030+ case isc_info_error:
10031+ // don't return false here, as we not put error into status
10032+ return true;
10033+ /* uncomment to show error (isc_infunk) instead
10034+ {
10035+ ISC_STATUS errs[3] = { isc_arg_gds, 0, isc_arg_end };
10036+ auto b = p.getBytes();
10037+ errs[1] = isc_portable_integer(b + 1, p.getClumpLength() - 1);
10038+ fbStatus->setErrors(errs);
10039+ return false;
10040+ }*/
10041+
10042+ default:
10043+ fb_assert(false);
10044+ break;
10045+ }
10046+
10047+ if (pField)
10048+ {
10049+ const FB_UINT64 val = p.getBigInt();
10050+ *pField = initial ? val : val - *pField;
10051+ }
10052+ }
10053+
10054+ return true;
10055+ }
10056+
10057+ bool IsqlWireStats::print(bool initial)
10058+ {
10059+ if (!get(initial))
10060+ {
10061+ ISQL_errmsg(fbStatus);
10062+ return false;
10063+ }
10064+
10065+ IUTILS_printf2(Diag, "Wire logical statistics:%s", NEWLINE);
10066+ IUTILS_printf2(Diag, " send packets = %8" SQUADFORMAT "%s", m_out_packets, NEWLINE);
10067+ IUTILS_printf2(Diag, " recv packets = %8" SQUADFORMAT "%s", m_in_packets, NEWLINE);
10068+ IUTILS_printf2(Diag, " send bytes = %8" SQUADFORMAT "%s", m_out_bytes, NEWLINE);
10069+ IUTILS_printf2(Diag, " recv bytes = %8" SQUADFORMAT "%s", m_in_bytes, NEWLINE);
10070+
10071+ IUTILS_printf2(Diag, "Wire physical statistics:%s", NEWLINE);
10072+ IUTILS_printf2(Diag, " send packets = %8" SQUADFORMAT "%s", m_snd_packets, NEWLINE);
10073+ IUTILS_printf2(Diag, " recv packets = %8" SQUADFORMAT "%s", m_rcv_packets, NEWLINE);
10074+ IUTILS_printf2(Diag, " send bytes = %8" SQUADFORMAT "%s", m_snd_bytes, NEWLINE);
10075+ IUTILS_printf2(Diag, " recv bytes = %8" SQUADFORMAT "%s", m_rcv_bytes, NEWLINE);
10076+ IUTILS_printf2(Diag, " roundtrips = %8" SQUADFORMAT "%s", m_roundtrips, NEWLINE);
10077+
10078+ return true;
10079+ }
0 commit comments