<!-- 
RSS generated by JIRA (5.2.7#850-sha1:b2af0c8dc8537b36121c6a579fabbdf79fc919e5) at Thu May 23 01:22:43 UTC 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://www.doctrine-project.org/jira/si/jira.issueviews:issue-xml/DC-841/DC-841.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>Doctrine Project</title>
    <link>http://www.doctrine-project.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>5.2.7</version>
        <build-number>850</build-number>
        <build-date>21-02-2013</build-date>
    </build-info>

<item>
            <title>[DC-841] Doctrine_Connection_Mssql::replaceBoundParamsWithInlineValuesInQuery regex failing to replace all &apos;?&apos; instances [patch+]</title>
                <link>http://www.doctrine-project.org/jira/browse/DC-841</link>
                <project id="10031" key="DC">Doctrine 1</project>
                        <description>&lt;p&gt;When executing queries with WHERE statements using multiple instances of the &quot;&amp;lt;&amp;gt;&quot; operator (as well as other non &lt;tt&gt;=,(&lt;/tt&gt; symbols inbetween definitions), the method &lt;tt&gt;Doctrine_Connection_Mssql::replaceBoundParamsWithInlineValuesInQuery&lt;/tt&gt; fails to identify all ? replacements.&lt;/p&gt;

&lt;p&gt;In the following piece of code I have a query (trimmed for readability and renamed for privacy) that fails to have all &quot;?&quot; symbols replaced as well as the relevant code from the method mentioned above (minus the return statement) doing a simple demonstration:&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;&amp;lt;?php 
$query = &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; ? AND [t].[field2] &amp;lt;&amp;gt; ? AND [t].[field2] LIKE ?)&quot;;

$params = array(
	&quot;&apos;param1&apos;&quot;,
	&quot;&apos;param2&apos;&quot;,
	&quot;&apos;param3&apos;&quot;
);


/**
 * Replaces bound parameters and their placeholders with explicit values.
 *
 * Workaround for http://bugs.php.net/36561
 *
 * @param string $query
 * @param array $params
 */
//protected function replaceBoundParamsWithInlineValuesInQuery($query, array $params) {

	foreach($params as $key =&amp;gt; $value) {
		if(is_null($value)) {
			$value = &apos;NULL&apos;;
		}
		else {
			//$value = $this-&amp;gt;quote($value); //REMOVED AS PRE-ADDED QUOTES TO ABOVE PARAMETER LIST
		}

		$re = &apos;/([=,\(][^\\\&apos;]*)(\?)/iU&apos;;
		
		$matches = array();
		preg_match($re,$query,$matches);
		
		var_dump($matches); //ADDED FOR DEMONSTRATION

		$query = preg_replace($re, &quot;\\1 {$value}&quot;, $query, 1);
		
		var_dump($query); //ADDED FOR DEMONSTRATION
	}

//	return $query;
//
//}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Running this code produces: &lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;array(3) {
  [0]=&amp;gt;
  string(18) &quot;([t].[field1] &amp;lt;&amp;gt; ?&quot;
  [1]=&amp;gt;
  string(17) &quot;([t].[field1] &amp;lt;&amp;gt; &quot;
  [2]=&amp;gt;
  string(1) &quot;?&quot;
}
string(108) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt;  &apos;param1&apos; AND [t].[field2] &amp;lt;&amp;gt; ? AND [t].[field2] LIKE ?)&quot;
array(0) {
}
string(108) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt;  &apos;param1&apos; AND [t].[field2] &amp;lt;&amp;gt; ? AND [t].[field2] LIKE ?)&quot;
array(0) {
}
string(108) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt;  &apos;param1&apos; AND [t].[field2] &amp;lt;&amp;gt; ? AND [t].[field2] LIKE ?)&quot;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately the regex will not identify all the ? instances properly in the query when run like &lt;tt&gt;preg_match_all()&lt;/tt&gt;, which was my first idea to fix (pre-identify all ? instances, then go through and replace them).&lt;/p&gt;

&lt;p&gt;The only 3 potential solutions I can think of are:&lt;/p&gt;

&lt;p&gt;1. Pre-identify all ?&apos;s and note their position in the string, to do this using a much looser regex, then replace all the ?&apos;s found&lt;br/&gt;
2. Use a stack a loop and a switch statement to scan for eligible ? replacements. I have some sample code that shows this should work, but performance is not something I have tested.&lt;br/&gt;
3. Revert back to the previous behavior. Scanning the changelogs I really don&apos;t know where this broke, other than queries that worked prior to 1.2.3 have since broken and this method is the cause.&lt;/p&gt;</description>
                <environment>PHP 5.2.11, Apache, Microsoft SQL Server 2005</environment>
            <key id="11826">DC-841</key>
            <summary>Doctrine_Connection_Mssql::replaceBoundParamsWithInlineValuesInQuery regex failing to replace all &apos;?&apos; instances [patch+]</summary>
                <type id="1" iconUrl="http://www.doctrine-project.org/jira/images/icons/issuetypes/bug.png">Bug</type>
                                <priority id="3" iconUrl="http://www.doctrine-project.org/jira/images/icons/priorities/major.png">Major</priority>
                    <status id="1" iconUrl="http://www.doctrine-project.org/jira/images/icons/statuses/open.png">Open</status>
                    <resolution id="-1">Unresolved</resolution>
                                <assignee username="jwage">Jonathan H. Wage</assignee>
                                <reporter username="dcousineau">Daniel Cousineau</reporter>
                        <labels>
                    </labels>
                <created>Wed, 25 Aug 2010 18:14:54 +0000</created>
                <updated>Sat, 5 Mar 2011 17:54:59 +0000</updated>
                                    <version>1.2.3</version>
                                                <component>Connection</component>
                        <due></due>
                    <votes>3</votes>
                        <watches>4</watches>
                        <comments>
                    <comment id="14072" author="dcousineau" created="Wed, 25 Aug 2010 18:18:41 +0000"  >&lt;p&gt;I am probably way over thinking a solutions, however since I have to run home and don&apos;t have time to flesh this out further at the moment, my initial idea is something like this:&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;&amp;lt;?php 
$query = &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; &apos;Testing!?&apos; AND [t].[field2] &amp;lt;&amp;gt; ? AND [t].[field?] LIKE ? AND [t].[field3] = ?)&quot;;

$params = array(
	&quot;&apos;param1&apos;&quot;,
	&quot;param2?&quot;,
	&quot;&apos;param3&apos;&quot;
);

var_dump($query);

$stack = array();
$stringDelim = array(&quot;&apos;&quot;, &apos;&quot;&apos;);

$i = 0;
foreach( str_split($query) as $char )
{
	switch($char) {
		
		case &quot;[&quot;:
			if( !in_array(end($stack), $stringDelim) )
				array_push($stack, $char);
			
			break;
			
		case &quot;]&quot;:
			if( end($stack) == &quot;[&quot; ) {
				array_pop($stack);
			} else
				array_push($stack, $char);
				
			break;
		
		case &quot;\&quot;&quot;:
		case &quot;&apos;&quot;:
			if( end($stack) == $char )
				array_pop($stack);
			else
				array_push($stack, $char);
			
			break;
		
		case &quot;?&quot;:
			if( !in_array(end($stack), array_merge($stringDelim, array(&quot;[&quot;, &quot;]&quot;))) )
			{
				$param = array_shift($params);
				$query = substr_replace($query, $param, $i, 1);
				
				$i += strlen($param) - 1;
				var_dump($query);
			}
			
			
			break;
		
		default:
	}
	
	$i++;
}

var_dump($query);
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Which produces&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;string(131) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; &apos;Testing!?&apos; AND [t].[field2] &amp;lt;&amp;gt; ? AND [t].[field?] LIKE ? AND [t].[field3] = ?)&quot;
string(138) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; &apos;Testing!?&apos; AND [t].[field2] &amp;lt;&amp;gt; &apos;param1&apos; AND [t].[field?] LIKE ? AND [t].[field3] = ?)&quot;
string(144) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; &apos;Testing!?&apos; AND [t].[field2] &amp;lt;&amp;gt; &apos;param1&apos; AND [t].[field?] LIKE param2? AND [t].[field3] = ?)&quot;
string(151) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; &apos;Testing!?&apos; AND [t].[field2] &amp;lt;&amp;gt; &apos;param1&apos; AND [t].[field?] LIKE param2? AND [t].[field3] = &apos;param3&apos;)&quot;
string(151) &quot;SELECT * FROM [table] AS [t] WHERE ([t].[field1] &amp;lt;&amp;gt; &apos;Testing!?&apos; AND [t].[field2] &amp;lt;&amp;gt; &apos;param1&apos; AND [t].[field?] LIKE param2? AND [t].[field3] = &apos;param3&apos;)&quot;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Which is what we would expect, as well as it doesn&apos;t take into account for newly inserted data containing &apos;?&apos; symbols.&lt;/p&gt;

&lt;p&gt;But again this is just playing around with potential solutions.&lt;/p&gt;</comment>
                    <comment id="14113" author="enrico" created="Fri, 27 Aug 2010 10:54:27 +0000"  >&lt;p&gt;The patch for &lt;a href=&quot;http://www.doctrine-project.org/jira/browse/DC-545&quot; title=&quot;MSSQL Server: Inserting blank records throws exception / Invalid casting of bound query parameters in sub-selects.&quot;&gt;&lt;del&gt;DC-545&lt;/del&gt;&lt;/a&gt; broke some queries or didn&apos;t worked at all. Unfortunately there was no Test Case for &lt;a href=&quot;http://www.doctrine-project.org/jira/browse/DC-545&quot; title=&quot;MSSQL Server: Inserting blank records throws exception / Invalid casting of bound query parameters in sub-selects.&quot;&gt;&lt;del&gt;DC-545&lt;/del&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The patch and a Test Case can be found at: &lt;a href=&quot;http://github.com/estahn/doctrine1/compare/master...DC-841&quot; class=&quot;external-link&quot;&gt;http://github.com/estahn/doctrine1/compare/master...DC-841&lt;/a&gt;&lt;/p&gt;
</comment>
                    <comment id="14233" author="enrico" created="Thu, 2 Sep 2010 08:01:50 +0000"  >&lt;p&gt;I made a mistake with github, the updated branch can be found at&lt;br/&gt;
&lt;a href=&quot;http://github.com/estahn/doctrine1/tree/DC-841-2&quot; class=&quot;external-link&quot;&gt;http://github.com/estahn/doctrine1/tree/DC-841-2&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="15465" author="rotoclap" created="Sat, 5 Mar 2011 17:54:59 +0000"  >&lt;p&gt;Doesn&apos;t work with :&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-sql&quot;&gt;&apos;Test&apos; &amp;lt;&amp;gt; &apos;Test !?&apos;
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The question mark is captured...&lt;/p&gt;

&lt;p&gt;This code seems working :&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;foreach($params as $key =&amp;gt; $value) {
  &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt;(is_null($value)) {
    $value = &apos;NULL&apos;;
  }
  &lt;span class=&quot;code-keyword&quot;&gt;else&lt;/span&gt; {
    $value = $&lt;span class=&quot;code-keyword&quot;&gt;this&lt;/span&gt;-&amp;gt;quote($value);
  }

  $re = &apos;/((?:[=&amp;lt;&amp;gt;,\(]|LIKE|IS)[^\\\&apos;]*)(\?)/iuU&apos;;

  $query = preg_replace($re, &lt;span class=&quot;code-quote&quot;&gt;&quot;\\1 {$value}&quot;&lt;/span&gt;, $query, 1);
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</comment>
                </comments>
                    <attachments>
                </attachments>
            <subtasks>
        </subtasks>
        </item>
</channel>
</rss>