View Issue Details

IDProjectCategoryView StatusLast Update
0035549mantisbtplug-inspublic2026-04-07 11:38
Reporterraspopov Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status acknowledgedResolutionopen 
Product Version2.27.1 
Summary0035549: MantisGraph APPLICATION ERROR 401 with SQLite
Description

When the /plugin.php?page=MantisGraph/issues_trend_graph.php page is opened, the following error is displayed:

APPLICATION ERROR 401

Database query failed. Error received from database was #0: 0 for the query: SELECT
FLOOR(date_submitted / 86400) date_index,
COUNT(*) num
FROM mantis_bug_table
WHERE project_id=1 AND mantis_bug_table.id IN (SELECT mantis_bug_table.id FROM mantis_bug_table JOIN mantis_project_table ON mantis_project_table.id = mantis_bug_table.project_id WHERE mantis_project_table.enabled = ? AND (mantis_bug_table.project_id = ?)) GROUP BY date_index.

Please use the "Back" button in your web browser to return to the previous page. There you can correct whatever problems were identified in this error or select another action. You can also click an option from the menu bar to go directly to a new section.
Detailed error information
Full path: C:\Projects\mantisbt\core\classes\DbQuery.class.php
Line number: 298
Stack trace
#   Filename    Line    Class   Type    Function    Args
0   C:\Projects\mantisbt\core\classes\DbQuery.class.php 298 -   -   trigger_error   <string>'401', <integer>256
1   C:\Projects\mantisbt\core\classes\DbQuery.class.php 257 DbQuery ->  db_execute  <NULL>NULL, <NULL>NULL
2   C:\Projects\mantisbt\core\classes\DbQuery.class.php 811 DbQuery ->  execute -
3   C:\Projects\mantisbt\plugins\MantisGraph\core\graph_api.php 512 DbQuery ->  fetch   -
4   C:\Projects\mantisbt\plugins\MantisGraph\pages\issues_trend_graph.php   50  -   -   create_cumulative_bydate    <array> { ['_version'] => 'v9', ['_view_type'] => 'simple', ['category_id'] => <array> { [0] => '0' }, ['severity'] => <array> { [0] => 0 }, ['status'] => <array> { [0] => 0 }, ['highlight_changed'] => 6, ['reporter_id'] => <array> { [0] => 0 }, ['handler_id'] => <array> { [0] => 0 }, ['project_id'] => <array> { [0] => -3 }, ['projection'] => <array> { [0] => 0 }, ['resolution'] => <array> { [0] => 0 }, ['build'] => <array> { [0] => '0' }, ['version'] => <array> { [0] => '0' }, ['hide_status'] => <array> { [0] => -2 }, ['monitor_user_id'] => <array> { [0] => 0 }, ['sort'] => 'last_updated', ['dir'] => 'DESC', ['per_page'] => 50, ['match_type'] => 0, ['platform'] => <array> { [0] => '0' }, ['os'] => <array> { [0] => '0' }, ['os_build'] => <array> { [0] => '0' }, ['fixed_in_version'] => <array> { [0] => '0' }, ['target_version'] => <array> { [0] => '0' }, ['profile_id'] => <array> { [0] => 0 }, ['priority'] => <array> { [0] => 0 }, ['note_user_id'] => <array> { [0] => 0 }, ['sticky'] => true, ['filter_by_date'] => false, ['start_month'] => '03', ['end_month'] => '03', ['start_day'] => 1, ['end_day'] => '07', ['start_year'] => '2025', ['end_year'] => '2025', ['filter_by_last_updated_date'] => false, ['last_updated_start_month'] => '03', ['last_updated_end_month'] => '03', ['last_updated_start_day'] => 1, ['last_updated_end_day'] => '07', ['last_updated_start_year'] => '2025', ['last_updated_end_year'] => '2025', ['search'] => '', ['view_state'] => 0, ['tag_string'] => '', ['tag_select'] => 0, ['relationship_type'] => -1, ['relationship_bug'] => 0, ['custom_fields'] => <array> { } }
5   C:\Projects\mantisbt\plugin.php 74  -   -   include <string>'C:\\Projects\\mantisbt\\plugins\\MantisGraph\\pages\\issues_trend_graph.php'

All other pages of MantisGraph work fine.

This only happens on PHP 7.4, everything displays fine on PHP 8.3.

Additional Information

Debug Log has the one additional event in the PHP 8.4 that is missing in the PHP 7.4 case:

DB graph_api.php:552 create_cumulative_bydate() array (
  0 => 'SELECT
    FLOOR(COALESCE(max_date_modified, last_updated) / 86400 ) date_index,
    COUNT(*) num
FROM mantis_bug_table
LEFT JOIN(
    SELECT bug_id, MAX(date_modified) max_date_modified
    FROM mantis_bug_history_table
    WHERE field_name = \'status\' AND new_value >= \'80\' AND old_value < \'80\'
    GROUP BY bug_id
) hist ON hist.bug_id =mantis_bug_table.id
WHERE  project_id=1
    AND mantis_bug_table.status >= 80 AND mantis_bug_table.id IN (SELECT mantis_bug_table.id FROM mantis_bug_table JOIN mantis_project_table ON mantis_project_table.id = mantis_bug_table.project_id WHERE mantis_project_table.enabled = \'1\' AND (mantis_bug_table.project_id = 1)) GROUP BY date_index',
  1 => '0.0002',
)

Empty database, one project (id=1), no issues. Branch: master.

TagsNo tags attached.

Relationships

related to 0010573 acknowledged support SQLite 
related to 0034042 closeddregad MantisGraph: inefficient calculation of data sets for Issue Trends graph 

Activities

dregad

dregad

2025-03-07 12:21

developer   ~0069957

I'm not able to reproduce this on my dev box. Maybe it's caused by specific database settings ?

What happens when you run the query against the database directly ?

raspopov

raspopov

2025-03-10 11:55

reporter   ~0069975

Last edited: 2025-03-10 12:03

Database query failed. Error received from database was #0: 0

It does not actually say '0', but that FLOOR is an unknown identifier.
PR for ADODb to fix this zero message: https://github.com/ADOdb/ADOdb/issues/1061

PHP 7.4 comes with SQLite 3.31, which does not have the FLOOR function.
PHP 8.4 ships with SQLite 3.46 and doesn't have this feature either.
So why did it work for me? Because I put the newer SQLite 3.48 library in the PHP 8.4 directory and forgot about it, FLOOR is supported in it.
It looks like SQLite for FLOOR should be compiled with the SQLITE_ENABLE_MATH_FUNCTIONS flag.

By the way, is it mandatory to use this function in the MantisGraph plugin, or can we somehow get by without it?

dregad

dregad

2025-03-10 13:27

developer   ~0069977

Well it would have been worth mentioning somewhere that you were using SQLite, which is not (yet at least - see 0010573) supported - I was assuming you were on MySQL...

is it mandatory to use this function in the MantisGraph plugin, or can we somehow get by without it?

It is not, really. The requirement is to get an integer value without rounding, so floor was the most logical choice when I refactored graph_api.php last year. I'm fine with using an alternative as long as we get the same results. And we're dealing with unix timestamps here, so only positive values.

PHP 7.4 comes with SQLite 3.31, which does not have the FLOOR function.
PHP 8.4 ships with SQLite 3.46 and doesn't have this feature either.

I'm a bit surprised by this statement, because to my knowledge libsqlite3 is no longer bundled since 7.4, so PHP should use whatever version is installed on the system.

According to the SQLite change log, built-in math functions should be available since 3.35.0, assuming it has been compiled with the appropriate flag as you pointed out (which is the case on Ubuntu and Windows). So we could also decide to require this minimum version (and make sure.

raspopov

raspopov

2025-03-10 14:19

reporter   ~0069978

Well it would have been worth mentioning somewhere that you were using SQLite

Yes, indeed. I almost always use SQLite and I don't even notice it anymore.

I'm a bit surprised by this statement

I am using PHP For Windows which is available here: https://windows.php.net/download/

dregad

dregad

2025-03-21 20:25

developer   ~0070016

Upstream issue https://github.com/ADOdb/ADOdb/issues/1061 has been fixed and will be released with ADOdb 5.22.9 (no announced date yet).

raspopov

raspopov

2026-01-18 10:33

reporter   ~0070718

Last edited: 2026-01-18 10:36

It seems that all new versions of PHP for Windows still come with a compiled SQLite that lacks the math option. -_-
A simple alternative solution is to replace "FLOOR(x)" with "ROUND(x - 0.5)".

raspopov

raspopov

2026-03-13 11:37

reporter   ~0070868

PR: https://github.com/mantisbt/mantisbt/pull/2197

dregad

dregad

2026-03-13 14:31

developer   ~0070869

A simple alternative solution is to replace "FLOOR(x)" with "ROUND(x - 0.5)".

Mathematically not identical, but since we are only dealing with positive values (timestamps) here, that should not be an issue here.

That said, the behavior of ROUND is sometimes unexpected, for example in MySQL

ROUND() uses the following rules depending on the type of the first argument:

For exact-value numbers, ROUND() uses the “round half away from zero” or “round toward nearest” rule: A value with a fractional part of .5 or greater is rounded up to the next integer if positive or down to the next integer if negative. (In other words, it is rounded away from zero.) A value with a fractional part less than .5 is rounded down to the next integer if positive or up to the next integer if negative.

For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest even” rule: A value with a fractional part exactly halfway between two integers is rounded to the nearest even integer.

For example:

mysql> select round(0.5), round(cast(0.5 as float));
+------------+---------------------------+
| round(0.5) | round(cast(0.5 as float)) |
+------------+---------------------------+
|          1 |                         0 |
+------------+---------------------------+

So I'm a bit concern, and think that this should be carefully tested. Especially considering that SQLITE support is at this stage an experimental thing that only you are using...

Moreover, some DB's require a 2nd param for precision (e.g. for mssql round(x, 0)).

raspopov

raspopov

2026-03-13 15:18

reporter   ~0070870

Oh! That's an idea - let's use “CAST”.

dregad

dregad

2026-03-14 06:32

developer   ~0070871

let's use “CAST”

Hmmm. We're going to have SQL portability issues with that.

mysql> select cast(0.5 as integer);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'integer)' at line 1

mysql> select cast(0.5 as unsigned);
+-----------------------+
| cast(0.5 as unsigned) |
+-----------------------+
|                     1 |
+-----------------------+
1 row in set (0.001 sec)

So CAST seems to perform rounding too (although not on all DBs), which was unexpected and means it's no different from using ROUND and gets us back to my earlier concern...

raspopov

raspopov

2026-03-14 07:44

reporter   ~0070874

In fact, in both of these expressions, the variable $t_seconds_per_day contains the integer 86400, and—at least in SQLite—the calculations are performed as integer operations in any case. And the rounding functions do nothing.

dregad

dregad

2026-03-14 09:18

developer   ~0070877

the calculations are performed as integer operations in any case

Integer division is an interesting idea, however not all DBs are doing it.

  • / performs an integer division with MS SQL Server, PostgreSQL, SQLite
  • On MySQL, MariaDB and Oracle, the result is a float.

MySQL has DIV operator, Oracle has \.

So the solution might be to determine the operator to use based on the DB being used.

raspopov

raspopov

2026-03-16 11:22

reporter   ~0070887

SQLite supports ROUND(x,d); I think this is the most compatible option. PR updated.

vboctor

vboctor

2026-04-04 20:42

manager   ~0070939

@raspopov I spent sometime today reviewing / testing sqlite and provided some suggestions. It would be good to keep a running list of what is remaining to enable merging - e.g. adodb dev-master dependency. I'm looking forward to this being merged.

raspopov

raspopov

2026-04-05 13:29

reporter   ~0070940

@vboctor, Thank you for your time. As I understand it, @mnewnham has joined the SQLite implementation for ADODb, and he has his own plans for the necessary SQLite functionality in the library.