View Issue Details

IDProjectCategoryView StatusLast Update
0020479mantisbtdb postgresqlpublic2016-08-27 17:49
Reportergthomas Assigned Todregad  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version1.3.0-rc.1 
Target Version1.3.0-rc.2Fixed in Version1.3.0-rc.2 
Summary0020479: Error 401 db_query bind params starts with $2
Description

APPLICATION ERROR 401
Sikertelen adatbázis-lekérdezés. Az adatbázis hibaüzenete: #-1: ERROR: could not determine data type of parameter $1 a következő lekérdezéshez: SELECT project_id, access_level FROM mantis_project_user_list_table WHERE user_id=$2

Sikertelen adatbázis-lekérdezés. Az adatbázis hibaüzenete: #-1: ERROR: operator does not exist: smallint = boolean
LINE 1: ... 3, 5, 6, 2, 9) ) AND ( ( mantis_bug_table.status in ($1, $2...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. a következő lekérdezéshez: SELECT Count( DISTINCT mantis_bug_table.id ) as idcnt 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 in (1, 7, 4, 3, 5, 6, 2, 9) ) AND ( ( mantis_bug_table.status in ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26) ) )

Steps To Reproduce

For some users, the login page throws the first error.

For non-superuser users, the "View Issues" list produces query where the first bind param is "$2", not "$1".

I've implemented a crude hack: renumber the params in db_query. This works, but I don't know how to trace this problem to the root cause.

Additional Information

See attached patch

TagsNo tags attached.
Attached Files
MT20479.patch (1,235 bytes)   
diff --git a/core/database_api.php b/core/database_api.php
index 9fdca22..15abacc 100644
--- a/core/database_api.php
+++ b/core/database_api.php
@@ -387,11 +387,30 @@ function db_query( $p_query, array $p_arr_parms = null, $p_limit = -1, $p_offset
 							'%b' => db_param(),
 							'%l' => db_param(),
 							) );
+	log_event( LOG_DATABASE, "q=$p_query" );
+	$i = 0;
+	$p_off = 0;
+	$t_matches = array();
+	$t_query = $p_query;
+	$t_res = array();
+	while( 1 == preg_match('/[$][0-9]+/', $t_query, &$t_matches, PREG_OFFSET_CAPTURE ) ) {
+		$i++;
+		$t_res[] = substr( $t_query, 0, $t_matches[0][1] ) . '$' . $i;
+		$t_query = substr( $t_query, $t_matches[0][1] + strlen( $t_matches[0][0] ) );
+		$t_matches = array();
+	}
+	$t_query = implode( "", $t_res ) . $t_query;
+	if( 0 != strcmp( $p_query, $t_query ) ) {
+		log_event( LOG_DATABASE, "!!! $p_query\n<>\n$t_query" );
+		$p_query = $t_query;
+	}
 
 	if( db_is_oracle() ) {
 		$p_query = db_oracle_adapt_query_syntax( $p_query, $p_arr_parms );
 	}
 
+	log_event( LOG_DATABASE, "Q=$p_query P=" . var_export( $p_arr_parms, TRUE ) );
+
 	if( ( $p_limit != -1 ) || ( $p_offset != -1 ) ) {
 		$t_result = $g_db->SelectLimit( $p_query, $p_limit, $p_offset, $p_arr_parms );
 	} else {
MT20479.patch (1,235 bytes)   
MT20479-detailed_error.html (16,547 bytes)   
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
	<title>AEGON UNO-SOFT hibakövető</title>
	<link rel="stylesheet" type="text/css" href="https://www.unosoft.hu/mantis/aegon/css/default.css" />
	<link rel="stylesheet" type="text/css" href="https://www.unosoft.hu/mantis/aegon/css/jquery-ui-1.11.4.min.css" />
	<link rel="stylesheet" type="text/css" href="https://www.unosoft.hu/mantis/aegon/css/common_config.php" />
	<link rel="stylesheet" type="text/css" href="https://www.unosoft.hu/mantis/aegon/css/status_config.php" />
	<link rel="shortcut icon" href="/mantis/aegon/images/favicon.ico" type="image/x-icon" />
	<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Text Search" href="https://www.unosoft.hu/mantis/aegon/browser_search_plugin.php?type=text" />
	<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Issue Id" href="https://www.unosoft.hu/mantis/aegon/browser_search_plugin.php?type=id" />
	<script type="text/javascript" src="/mantis/aegon/javascript_config.php"></script>
	<script type="text/javascript" src="/mantis/aegon/javascript_translations.php"></script>
	<script type="text/javascript" src="/mantis/aegon/javascript/jquery-1.11.3.min.js"></script>
	<script type="text/javascript" src="/mantis/aegon/javascript/jquery-ui-1.11.4.min.js"></script>
	<script type="text/javascript" src="/mantis/aegon/javascript/common.js"></script>
	<script type="text/javascript" src="/mantis/aegon/javascript/bugFilter.js"></script>
</head>
<body>
<div id="mantis">
<div id="banner"><a id="logo-link" href="my_view_page.php"><img id="logo-image" alt="AEGON UNO-SOFT hibakövető" src="/mantis/aegon/config/mantis_logo.png" /></a></div><div id="error-msg"><div class="error-type">APPLICATION ERROR #401</div><div class="error-description">Sikertelen adatbázis-lekérdezés. Az adatbázis hibaüzenete: #-1: ERROR:  could not determine data type of parameter $1 a következő lekérdezéshez: SELECT p.id, p.name, ph.parent_id<br />
						  FROM mantis_project_table p<br />
						  LEFT JOIN mantis_project_user_list_table u<br />
						    ON p.id=u.project_id AND u.user_id=$2<br />
						  LEFT JOIN mantis_project_hierarchy_table ph<br />
						    ON ph.child_id = p.id<br />
						  WHERE p.enabled = $3 AND <br />
							( p.view_state=$4<br />
							    OR (p.view_state=$5<br />
								    AND<br />
							        u.user_id=$6 )<br />
							) ORDER BY p.name</div><div class="error-info">Kérjük, használja a böngészője "Vissza" gombját az előző oldalhoz való visszatéréshez. Ott kijavíthatja az imént felismert hibákat, vagy más műveletet választhat. A menüből szintén választhat egy pontot, ha közvetlenül az adott funkcióhoz szeretne jutni.</div><div class="error-details">		<table class="width90">
			<tr>
				<td>Full path: /home/aegon/prd/mantis/core/database_api.php</td>
			</tr>
			<tr>
				<td>Line: 469</td>
			</tr>
			<tr>
				<td>
					<table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">p_query</td><td style="width=70%; word-wrap:break-word; overflow:auto;">SELECT p.id, p.name, ph.parent_id
						  FROM mantis_project_table p
						  LEFT JOIN mantis_project_user_list_table u
						    ON p.id=u.project_id AND u.user_id=$2
						  LEFT JOIN mantis_project_hierarchy_table ph
						    ON ph.child_id = p.id
						  WHERE p.enabled = $3 AND 
							( p.view_state=$4
							    OR (p.view_state=$5
								    AND
							        u.user_id=$6 )
							) ORDER BY p.name</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">p_limit</td><td style="width=70%; word-wrap:break-word; overflow:auto;">-1</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">p_offset</td><td style="width=70%; word-wrap:break-word; overflow:auto;">-1</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">g_db_log_queries</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">boolean</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">t_db_type</td><td style="width=70%; word-wrap:break-word; overflow:auto;">pgsql</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">s_check_params</td><td style="width=70%; word-wrap:break-word; overflow:auto;">1</td><td style="width=10%;">boolean</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">t_start</td><td style="width=70%; word-wrap:break-word; overflow:auto;">1452023715.1661</td><td style="width=10%;">double</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">t_params</td><td style="width=70%; word-wrap:break-word; overflow:auto;">5</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">i</td><td style="width=70%; word-wrap:break-word; overflow:auto;">5</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">s_prefix</td><td style="width=70%; word-wrap:break-word; overflow:auto;">mantis_</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">s_suffix</td><td style="width=70%; word-wrap:break-word; overflow:auto;">_table</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">p_off</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">t_query</td><td style="width=70%; word-wrap:break-word; overflow:auto;">SELECT p.id, p.name, ph.parent_id
						  FROM mantis_project_table p
						  LEFT JOIN mantis_project_user_list_table u
						    ON p.id=u.project_id AND u.user_id=$1
						  LEFT JOIN mantis_project_hierarchy_table ph
						    ON ph.child_id = p.id
						  WHERE p.enabled = $2 AND 
							( p.view_state=$3
							    OR (p.view_state=$4
								    AND
							        u.user_id=$5 )
							) ORDER BY p.name</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">t_result</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">boolean</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">t_elapsed</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0004</td><td style="width=10%;">string</td></tr>
<tr><td colspan="3" style="word-wrap:break-word"><br /><strong>p_arr_parms</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;">180</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">1</td><td style="width=10%;">boolean</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">2</td><td style="width=70%; word-wrap:break-word; overflow:auto;">10</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">3</td><td style="width=70%; word-wrap:break-word; overflow:auto;">50</td><td style="width=10%;">integer</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">4</td><td style="width=70%; word-wrap:break-word; overflow:auto;">180</td><td style="width=10%;">integer</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>g_queries_array</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>1</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0012</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>2</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0005</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>3</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0004</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>4</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0006</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>5</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0004</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>6</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0004</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>7</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0006</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>8</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0017</td><td style="width=10%;">string</td></tr>
</table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>9</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;"></td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">0.0004</td><td style="width=10%;">string</td></tr>
</table></td></tr></table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>t_matches</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr></table></td></tr><tr><td colspan="3" style="word-wrap:break-word"><br /><strong>t_res</strong></td></tr><tr><td colspan="3"><table class="width100" style="table-layout:fixed;"><tr><th>Variable</th><th>Value</th><th>Type</th></tr><tr><td style="width=20%; word-wrap:break-word; overflow:auto;">0</td><td style="width=70%; word-wrap:break-word; overflow:auto;">SELECT p.id, p.name, ph.parent_id
						  FROM mantis_project_table p
						  LEFT JOIN mantis_project_user_list_table u
						    ON p.id=u.project_id AND u.user_id=$1</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">1</td><td style="width=70%; word-wrap:break-word; overflow:auto;">
						  LEFT JOIN mantis_project_hierarchy_table ph
						    ON ph.child_id = p.id
						  WHERE p.enabled = $2</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">2</td><td style="width=70%; word-wrap:break-word; overflow:auto;"> AND 
							( p.view_state=$3</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">3</td><td style="width=70%; word-wrap:break-word; overflow:auto;">
							    OR (p.view_state=$4</td><td style="width=10%;">string</td></tr>
<tr><td style="width=20%; word-wrap:break-word; overflow:auto;">4</td><td style="width=70%; word-wrap:break-word; overflow:auto;">
								    AND
							        u.user_id=$5</td><td style="width=10%;">string</td></tr>
</table></td></tr></table>				</td>
			</tr>
		</table>
</div><div class="error-trace"><table class="width90"><tr><th>Filename</th><th>Line</th><th></th><th></th><th>Function</th><th>Args</th></tr><tr class="row-1"><td>/home/aegon/prd/mantis/core/database_api.php</td><td>469</td><td>-</td><td>-</td><td>trigger_error</td><td>( &lt;string&gt;'401', &lt;integer&gt;256 )</td></tr><tr class="row-2"><td>/home/aegon/prd/mantis/core/user_api.php</td><td>991</td><td>-</td><td>-</td><td>db_query</td><td>( &lt;string&gt;'SELECT p.id, p.name, ph.parent_id
						  FROM {project} p
						  LEFT JOIN {project_user_list} u
						    ON p.id=u.project_id AND u.user_id=$2
						  LEFT JOIN {project_hierarchy} ph
						    ON ph.child_id = p.id
						  WHERE p.enabled = $3 AND 
							( p.view_state=$4
							    OR (p.view_state=$5
								    AND
							        u.user_id=$6 )
							) ORDER BY p.name', &lt;array&gt; { [0] =&gt; 180, [1] =&gt; true, [2] =&gt; 10, [3] =&gt; 50, [4] =&gt; 180 } )</td></tr><tr class="row-1"><td>/home/aegon/prd/mantis/core/filter_api.php</td><td>1196</td><td>-</td><td>-</td><td>user_get_accessible_projects</td><td>( &lt;integer&gt;180 )</td></tr><tr class="row-2"><td>/home/aegon/prd/mantis/view_all_bug_page.php</td><td>71</td><td>-</td><td>-</td><td>filter_get_bug_rows</td><td>( &lt;integer&gt;1, &lt;NULL&gt;NULL, &lt;NULL&gt;NULL, &lt;NULL&gt;NULL, &lt;NULL&gt;NULL, &lt;NULL&gt;NULL, &lt;NULL&gt;NULL, &lt;boolean&gt;true )</td></tr></table></div></div></div>
</body>
</html>
MT20479-detailed_error.html (16,547 bytes)   

Relationships

related to 0020483 closedcproensa Error 401 with PostgreSQL manage_user_page 
related to 0014398 closeddregad Support for PostgreSQL broken in 1.3 
has duplicate 0020896 closedcproensa APPLICATION ERROR 0000401 with view Issues - all Projects 
related to 0021649 closedcproensa Remove incorrectly placed db_param_push() 

Activities

gthomas

gthomas

2016-01-05 08:31

reporter   ~0052248

Ok, uploaded the patch (format has been dismissed...).

dregad

dregad

2016-01-05 09:34

developer   ~0052250

Edited the additional info field to point to attachment.

Looking at the error message, it seems you're using PostgreSQL, is this correct ?

It would be helpful if you could actually provide reproducible steps as I'm not able to reproduce the behavior on my dev box.

Maybe you can enable detailed errors reporting and post output here (after masking sensitive info if any), this way we get the call stack and variables.

gthomas

gthomas

2016-01-05 15:04

reporter   ~0052259

Thanks Damian!

Yes, it is PostgreSQL, v8.4.

I've attached the detailed report.
Maybe filter_api.php line 1127 (latest db_param() before the erroneous line 1196)?
How does db_param accumulate the count, and when it is reseted?

cproensa

cproensa

2016-01-06 09:38

developer   ~0052263

I am not using PostgreSQL, but i could find one trace that calls for db_param, for first time while building the query, but the param count was already 1.
Only could get this situation once, and haven't been able to reproduce again

The call stack was:


function access_cache_matrix_user

/var/www/html/git/mantis13_cpm/core/access_api.php.access_cache_matrix_user:162
/var/www/html/git/mantis13_cpm/core/access_api.php.access_get_local_level:629
/var/www/html/git/mantis13_cpm/core/access_api.php.access_get_project_level:282
/var/www/html/git/mantis13_cpm/core/access_api.php.access_has_project_level:330
/var/www/html/git/mantis13_cpm/core/helper_api.php.helper_get_current_project:358
/var/www/html/git/mantis13_cpm/core/config_api.php.config_get:118
/var/www/html/git/mantis13_cpm/core/lang_api.php.lang_language_exists:193
/var/www/html/git/mantis13_cpm/core/user_pref_api.php.user_pref_get_language:626
/var/www/html/git/mantis13_cpm/core/lang_api.php.lang_get_default:115
/var/www/html/git/mantis13_cpm/core/lang_api.php.lang_get_current:255
/var/www/html/git/mantis13_cpm/core/lang_api.php.lang_get:279
/var/www/html/git/mantis13_cpm/plugins/MantisCoreFormatting/MantisCoreFormatting.php.MantisCoreFormattingPlugin->register:30
/var/www/html/git/mantis13_cpm/core/classes/MantisPlugin.class.php.MantisPlugin->__construct:248
/var/www/html/git/mantis13_cpm/core/plugin_api.php.plugin_register:923
/var/www/html/git/mantis13_cpm/core/plugin_api.php.plugin_register_installed:965
/var/www/html/git/mantis13_cpm/core/plugin_api.php.plugin_init_installed:989
/var/www/html/git/mantis13_cpm/core.php.require_once:229
/var/www/html/git/mantis13_cpm/view_all_bug_page.php.{main}:39

Apparently, the upper callers were not building sql querys, so its not a case of nested builds

I am thinking of two issues:
1) Should core api code call db_param_push(), to keep safe of nested sql builds?
2) Sometimes, somewhere in the code a db_param call is used that doesnt get finalized with a db_query?

cproensa

cproensa

2016-01-07 17:11

developer   ~0052275

I managed to reproduce a similar situation:

Given projects A,B
Set A as current project
Go into advanced filters, and select specific project B (only that one)
Use the filter, and the error appears

APPLICATION ERROR 0000401
Database query failed. Error received from database was #-1: ERROR: could not determine data type of parameter $1 for the query: SELECT * FROM mantis_project_table WHERE id=$2.

Call trace:


/var/www/html/git/mantis13_pg/core/database_api.php.db_query:340
/var/www/html/git/mantis13_pg/core/project_api.php.project_cache_row:106
/var/www/html/git/mantis13_pg/core/project_api.php.project_exists:211
/var/www/html/git/mantis13_pg/core/filter_api.php.filter_get_bug_rows:1182
/var/www/html/git/mantis13_pg/view_all_bug_page.php.{main}:71

The problem is:
filter_api.php.filter_get_bug_rows is building the filter query, generating some where conditions, and calling db_param() to fill some of its values.
In the middle of that process, project_exists() is called. As the project B is not cached, the api function performs a sql query, which also uses db_param().
Internal parameter count was already on one, and returns the next one, that is 2.

So, to fix this, we may need to chase a lot of api functions that performs sql queries to add a db_param_push().

dregad

dregad

2016-01-08 05:01

developer   ~0052278

to fix this, we may need to chase a lot of api functions that performs sql queries to add a db_param_push()

You're absolutely right.

I created that API call exactly for that purpose, as I faced the same issue with PostgreSQL (and Oracle too) in another part of the application (I think it was custom fields).

To be perfectly clean, every single API executing SQL queries should make use of this, but it was too much effort go through the code and check functions one-by-one.

dregad

dregad

2016-01-08 08:29

developer   ~0052279

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

dregad

dregad

2016-01-08 08:37

developer   ~0052280

@gthomas,

I would appreciate if you could download the code from the mentioned pull request, and give it a test run to see if it resolves the issues you've encountered.

How does db_param accumulate the count, and when it is reseted?

There is a global variable in database API ($g_db_param), which acts like a stack. Everytime db_param() is called, the param count is incremented, and when the query is executed (calling db_query()), the count is reset to its previous value (or 0 if there is none).

gthomas

gthomas

2016-01-10 04:31

reporter   ~0052282

Thanks @cproense and @dregad!

I'll try the PR, but why do we use $number at all? With a global variable, this is very error prone.

Why not just a "?" or "<PLACEHOLDER>" or anything, and use a replacer (just as I did) just before execution? We already have such function for Oracle, already!

gthomas

gthomas

2016-01-10 15:06

reporter   ~0052286

As far as I could test it (only with specific users), f54b2de02e371e93624bb51d674ba24d0f1d1b06 solves this problem.

dregad

dregad

2016-05-15 09:00

developer   ~0053139

PR https://github.com/mantisbt/mantisbt/pull/705 has been rebased.

Related Changesets

MantisBT: master b6f81949

2016-05-21 00:19

dregad


Details Diff
Consistently push query params in all APIs

Fixes 0020479, https://github.com/mantisbt/mantisbt/pull/705
Affected Issues
0020479
mod - core/access_api.php Diff File
mod - core/api_token_api.php Diff File
mod - core/authentication_api.php Diff File
mod - core/billing_api.php Diff File
mod - core/bug_api.php Diff File
mod - core/bug_revision_api.php Diff File
mod - core/bugnote_api.php Diff File
mod - core/category_api.php Diff File
mod - core/cfdefs/cfdef_standard.php Diff File
mod - core/config_api.php Diff File
mod - core/custom_field_api.php Diff File
mod - core/database_api.php Diff File
mod - core/email_api.php Diff File
mod - core/email_queue_api.php Diff File
mod - core/file_api.php Diff File
mod - core/filter_api.php Diff File
mod - core/history_api.php Diff File
mod - core/install_helper_functions_api.php Diff File
mod - core/news_api.php Diff File
mod - core/plugin_api.php Diff File
mod - core/print_api.php Diff File
mod - core/profile_api.php Diff File
mod - core/project_api.php Diff File
mod - core/project_hierarchy_api.php Diff File
mod - core/relationship_api.php Diff File
mod - core/sponsorship_api.php Diff File
mod - core/summary_api.php Diff File
mod - core/tag_api.php Diff File
mod - core/tokens_api.php Diff File
mod - core/user_api.php Diff File
mod - core/user_pref_api.php Diff File
mod - core/version_api.php Diff File

MantisBT: master f3ab14c5

2016-05-23 01:54

dregad


Details Diff
Use correct function name db_param_push()

Commit fbc379faaf27e6b853c8b08ac380834836b81032 referenced the wrong
name db_push_param().

Issue 0020479
Affected Issues
0020479
mod - core/user_api.php Diff File