Welcome Guest, Not a member yet? Register   Sign In
CI_DB_driver::_protect_identifiers breaks when using table.* select
#1

[eluser]Unknown[/eluser]
Hi,

i seem to have stumbled on what looks like another "incompatibility" between _protect_identifiers() and the sql queries people want to see. Basically, if you try to select all fields from one table in a query, the star ("*") character gets the backtick treatment just as if it were a regular field name. Thus, by calling it like this:
Code:
$this->db->select('table.*')->get('table');
we get this:
Code:
SELECT `users`.`*` FROM (`users`)
instead of that:
Code:
SELECT `users`.* FROM (`users`)
It appears that the method does not check against reserved identifiers if it contains more than one segment that is also not an alias (the other cases do have the check). I hacked a small fix for that, in case someone else gets stuck with a similiar problem. All that's needed is to replace line 1281 in system/database/DB_driver.php:
Code:
$item = $this->_escape_identifiers($item);
with these four lines:
Code:
$last_part = array_pop($parts);
if(!in_array($last_part, $this->_reserved_identifiers))
    $item = $this->_escape_identifiers($item);
else
    $item = $this->_escape_identifiers(implode('.', $parts)).'.'.$last_part;
There. Hope that helps Smile

I'm not sure whether i should've filed a bug report for this, since there seem to be multiple other issues with this same function for other people...
#2

[eluser]elvix[/eluser]
$this->db->select() now accepts a second true/false parameter which will turn this behavior on/off/. It's been tripping up a lot of people lately, myself included. Smile
#3

[eluser]Colin Williams[/eluser]
Yeah. Just get that second TRUE param in there and you'll be good.
#4

[eluser]Jameson.[/eluser]
Quote:Just get that second TRUE param in there and you’ll be good.
Well, I don't want to go over all my models and some controllers and shove this TRUE param in all the selects just in case something else breaks suddenly next time. After all, protect function is there for some reason, right?

...And my broken query is similar but different.
Why oh why
SELECT *, DATE_FORMAT(some_date, "%d.%m.%Y")
turns into
SELECT *, DATE_FORMAT(some_date, `"%d`.`%m`.`%Y")`
Funny enough, dots in the request don't necessarily denote database/table/field delimiters.
#5

[eluser]Colin Williams[/eluser]
Quote:Well, I don’t want to go over all my models and some controllers and shove this TRUE param in all the selects just in case something else breaks suddenly next time. After all, protect function is there for some reason, right?

Even if you don't want to, you'll have to. A nice regex search/replace could probably do it.
#6

[eluser]Jameson.[/eluser]
Well, for one thing it has to be a FALSE as a second parameter :lol: and saying I will HAVE to do that is a little bit of an exaggeration. Feels quite comfortable with 1.6.3 now.
#7

[eluser]Colin Williams[/eluser]
Bah! My bad.




Theme © iAndrew 2016 - Forum software by © MyBB