Welcome Guest, Not a member yet? Register   Sign In
Possible bug when using select_max() and db prefix
#1

[eluser]Gone_Skiing[/eluser]
This is using the released 1.7.0 version. I have not checked to see if this has been fixed in the tip code.

The select_max() active record function uses the _max_min_avg_sum() function. In this function the selection string passed in gets processed through the _protect_identifiers() function which adds the table prefix (if one is being used). The protected string gets put into the MAX() sql function. This string gets added to the array of select tokens (ar_select[]).

The problem is that the normal select() active record function simply adds the selection to the ar_select[] array without calling _protect_identifiers(). When the get() function is called it traverses the ar_select[] array and calls _protect_identifiers() on each element of the array and then comma concatenates them to make the select portion of the the SQL query. Unfortunately one of the elements is the MAX() statement (or MIN, AVG, SUM). _protect_identifiers() then adds the prefix to the MAX() statement.

A couple fixes that I thought of would be:
- Alter _protect_identifiers() to ignore the MAX, MIN, AVG, etc types (same issue arises with DATE functions too). Down side is that the _protect_identifiers() function would need an exhaustive list of keywords to ignore.

- Add a protected flag to the ar_select[] elements so that get() doesn't call _protect() again

- Change all the select() flavours to call_protect_identifiers() before adding the selection to the ar_select[] array. Remove the call to _protect_identifiers() from the get() function.

Thanks,

-Nick
#2

[eluser]Gone_Skiing[/eluser]
Ok, I found a different solution.

I see that there is code in _protect_identifiers() to simply return if there is a '(' in the string. However this piece of code follows the section that will process the statement if there is a '.' in the string.

I moved this code:
Code:
DB_driver.php:1287
        // This is basically a bug fix for queries that use MAX, MIN, etc.
        // If a parenthesis is found we know that we do not need to
        // escape the data or add a prefix.  There's probably a more graceful
        // way to deal with this, but I'm not thinking of it -- Rick
        if (strpos($item, '(') !== FALSE)
        {
            return $item.$alias;
        }

Up to line 1239.

-Nick




Theme © iAndrew 2016 - Forum software by © MyBB