From deb5f480dc4e0c77a1d66e8bbbd7012e2a3b079f Mon Sep 17 00:00:00 2001 From: Liviu-Mihail Concioiu Date: Sat, 18 Jan 2025 21:54:57 +0100 Subject: [PATCH] Implement getValuesForCsvTable Signed-off-by: Liviu-Mihail Concioiu --- .../Database/StructureController.php | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/libraries/classes/Controllers/Database/StructureController.php b/libraries/classes/Controllers/Database/StructureController.php index 19d9f7d4cb19..c35e45db785c 100644 --- a/libraries/classes/Controllers/Database/StructureController.php +++ b/libraries/classes/Controllers/Database/StructureController.php @@ -726,6 +726,12 @@ protected function getStuffForEngineTypeTable( $sumSize ); break; + case 'CSV': + [$currentTable, $formattedSize, $unit, $sumSize] = $this->getValuesForCsvTable( + $currentTable, + $sumSize, + ); + break; // Mysql 5.0.x (and lower) uses MRG_MyISAM // and MySQL 5.1.x (and higher) uses MRG_MYISAM // Both are aliases for MERGE @@ -883,6 +889,74 @@ protected function getValuesForInnodbTable( ]; } + /** + * Get values for CSV table + * + * https://bugs.mysql.com/bug.php?id=53929 + * + * @param array $currentTable current table + * @param int $sumSize sum size + * + * @return array + */ + protected function getValuesForCsvTable( + array $currentTable, + $sumSize, + ) { + $formattedSize = $unit = ''; + + if ( + (in_array($currentTable['ENGINE'], ['CSV'], true) + && $currentTable['TABLE_ROWS'] < $GLOBALS['cfg']['MaxExactCount']) + || ! isset($currentTable['TABLE_ROWS']) + ) { + $currentTable['COUNTED'] = true; + $currentTable['TABLE_ROWS'] = $this->dbi + ->getTable($this->db, $currentTable['TABLE_NAME']) + ->countRecords(true); + } else { + $currentTable['COUNTED'] = false; + } + + if ($this->isShowStats) { + // Only count columns that have double quotes + $columnCount = (int) $this->dbi->fetchValue( + 'SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = \'' + . $this->dbi->escapeString($this->db) . '\' AND TABLE_NAME = \'' + . $this->dbi->escapeString($currentTable['TABLE_NAME']) . '\' AND NUMERIC_SCALE IS NULL;' + ); + + // Get column names + $columnNames = $this->dbi->fetchValue( + 'SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = \'' + . $this->dbi->escapeString($this->db) . '\' AND TABLE_NAME = \'' + . $this->dbi->escapeString($currentTable['TABLE_NAME']) . '\';' + ); + + // 10Mb buffer for CONCAT_WS + // not sure if is needed + $this->dbi->query('SET SESSION group_concat_max_len = 10 * 1024 * 1024'); + + // Calculate data length + $dataLength = (int) $this->dbi->fetchValue(" + SELECT SUM(CHAR_LENGTH(REPLACE(REPLACE(REPLACE( + CONCAT_WS(',', $columnNames), UNHEX('0A'), 'nn'), UNHEX('22'), 'nn'), UNHEX('5C'), 'nn' + ))) FROM " . Util::backquote($this->db) . '.' . Util::backquote($currentTable['TABLE_NAME']) + ); + + // Calculate quotes length + $quotesLength = $currentTable['TABLE_ROWS'] * $columnCount * 2; + + /** @var int $tblsize */ + $tblsize = $dataLength + $quotesLength + $currentTable['TABLE_ROWS']; + + $sumSize += $tblsize; + [$formattedSize, $unit] = Util::formatByteDown($tblsize, 3, $tblsize > 0 ? 1 : 0); + } + + return [$currentTable, $formattedSize, $unit, $sumSize]; + } + /** * Get values for Mroonga table *