-
Incident report
-
Resolution: Unresolved
-
Trivial
-
None
-
2.4.6
According to zabbix sources there are only 3 places which may return so short data:
include/classes/db/DB.php:
protected static function reserveIds($table, $count) { global $DB; $tableSchema = self::getSchema($table); $id_name = $tableSchema['key']; $sql = 'SELECT nextid'. ' FROM ids'. ' WHERE table_name='.zbx_dbstr($table). ' AND field_name='.zbx_dbstr($id_name); // SQLite3 does not support this syntax. Since we are in transaction, it can be ignored. if ($DB['TYPE'] != ZBX_DB_SQLITE3) { $sql = $sql.' FOR UPDATE'; } $res = DBfetch(DBselect($sql)); if ($res) { $maxNextId = bcadd($res['nextid'], $count, 0); if (bccomp($maxNextId, ZBX_DB_MAX_ID) == 1) { $nextid = self::refreshIds($table, $count); } else { $sql = 'UPDATE ids'. ' SET nextid='.$maxNextId. ' WHERE table_name='.zbx_dbstr($table). ' AND field_name='.zbx_dbstr($id_name); if (!DBexecute($sql)) { self::exception(self::DBEXECUTE_ERROR, 'DBEXECUTE_ERROR'); } $nextid = bcadd($res['nextid'], 1, 0); } } else { $nextid = self::refreshIds($table, $count); } return $nextid; } ... private static function refreshIds($table, $count) { $tableSchema = self::getSchema($table); $id_name = $tableSchema['key']; // when we reach the maximum ID, we try to refresh them to check if any IDs have been freed $sql = 'DELETE FROM ids WHERE table_name='.zbx_dbstr($table).' AND field_name='.zbx_dbstr($id_name); if (!DBexecute($sql)) { self::exception(self::DBEXECUTE_ERROR, 'DBEXECUTE_ERROR'); } $row = DBfetch(DBselect('SELECT MAX('.$id_name.') AS id FROM '.$table)); $nextid = ($row && $row['id']) ? $row['id'] : 0; $maxNextId = bcadd($nextid, $count, 0); if (bccomp($maxNextId, ZBX_DB_MAX_ID) == 1) { self::exception( self::RESERVEIDS_ERROR, __METHOD__.' ID greater than maximum allowed for table "'.$table.'"' ); } $sql = 'INSERT INTO ids (table_name,field_name,nextid)'. ' VALUES ('.zbx_dbstr($table).','.zbx_dbstr($id_name).','.$maxNextId.')'; if (!DBexecute($sql)) { self::exception(self::DBEXECUTE_ERROR, 'DBEXECUTE_ERROR'); } $nextid = bcadd($nextid, 1, 0); return $nextid; }
Question is - why we don't return more details to distinguish those 3 different cases, including failed SQL ?
It would help to troubleshoot unclear problems.
For example we have code like this:
$sql = 'INSERT INTO '.$table.' ('.implode(',', array_keys($row)).')'. ' VALUES ('.implode(',', array_values($row)).')'; if (!DBexecute($sql)) { self::exception(self::DBEXECUTE_ERROR, _s('SQL statement execution has failed "%1$s".', $sql)); }
Why would not reuse it for those 3 cases too ?