SELECT COUNT(*) AS expression FROM (SELECT 1 AS expression FROM {node} node INNER JOIN {field_data_field_term_type} field_data_field_term_type ON node.nid = field_data_field_term_type.entity_id AND (field_data_field_term_type.entity_type = :views_join_condition_0 AND field_data_field_term_type.deleted = :views_join_condition_1) WHERE (( (node.status = :db_condition_placeholder_0) AND (node.type IN (:db_condition_placeholder_1)) AND (node.language IN (:db_condition_placeholder_2)) AND (field_data_field_term_type.field_term_type_tid = :db_condition_placeholder_3) AND (field_data_field_term_type.field_term_type_tid = :field_data_field_term_type_field_term_type_tid ) ))) subquery (prepared: SELECT COUNT(*) AS expression FROM (SELECT 1 AS expression FROM "NODE" node INNER JOIN "FIELD_DATA_FIELD_TERM_TYPE" field_data_field_term_type ON node.nid = field_data_field_term_type.entity_id AND (field_data_field_term_type.entity_type = :views_join_condition_0 AND field_data_field_term_type.deleted = :views_join_condition_1) WHERE (( (node.status = :db_condition_placeholder_0) AND (node.type IN (:db_condition_placeholder_1)) AND (node.language IN (:db_condition_placeholder_2)) AND (field_data_field_term_type.field_term_type_tid = :db_condition_placeholder_3) AND (field_data_field_term_type.field_term_type_tid = :L#2253 ) ))) subquery ) e: SQLSTATE[HY000]: General error 1036: OCIBindByName: ORA-01036: illegal variable name/number (/tmp/PDO_OCI-1.0/oci_statement.c:287) args: Array ( [:db_condition_placeholder_0] => 1 [:db_condition_placeholder_1] => article [:db_condition_placeholder_2] => en [:db_condition_placeholder_3] => 1 [:field_data_field_term_type_field_term_type_tid] => test123 [:views_join_condition_0] => node [:views_join_condition_1] => 0 )
I found this problem when using Views module with contextual filters. Any idea on how to fix this or give me some clues on how to fix it?
| Comment | File | Size | Author |
|---|---|---|---|
| #34 | oracle_placeholder_collision-1153174-34.patch | 904 bytes | sionescu |
| #32 | oracle_placeholder_collision-1153174-32.patch | 903 bytes | sionescu |
| #22 | oracle_placeholder_collision-1153174-22.patch | 692 bytes | sionescu |
Comments
Comment #1
aaaristo commentedThe problem here is :field_data_field_term_type_field_term_type_tid that becomes :L#2253...
because it is too long for oracle identifiers. It looks like oracle does not like # in bind variable
names. This is indeed a driver bug..
Comment #2
arrancia commentedIs this placeholder inserted by the driver or the views module, if it's inserted by the driver it can be easily changed. So we can leave the databases already created intact just change the name of the placeholders.
Comment #3
aaaristo commentedBy the driver. And of course we have to rename it.. just no time to do it now, why don't you try to contribute a patch?
Comment #4
arrancia commentedI will, i am just figuring it out :D
Comment #5
arrancia commentedOk first the problem is that the long identifier in the query gets replaed but not in the bind array.
Second the problem is that not that oracle doesnt want # in the bind names but it doesnt want long bind names.
So i think maybe i can implement all bind% functions in DatabaseStatement__oracle and call parent::bind% and rewrite all keys of the binds so that they would become also shortened.
What do you think about this?
Comment #6
aaaristo commentedi think the better approach is simply to change the long identifier prefix to replace # with a bind variable supported character...
Comment #7
arrancia commentedBut # is supported i tried it on a query like this
db_query( "SELECT :L#12345 FROM DUAL" , array( ":L#12345" => 'Hello world' ) );
and it works,
what happens now is this:
db_query( "SELECT :L#12345 FROM DUAL" , array( "the_real_long_identifier" => 'Hello world' ) );
this bug happens because the keys in the array are not replaced with the long identifier shortener so that's why the error ORA-01036: illegal variable name/number
If you see the not prepared query above:
AND (field_data_field_term_type.field_term_type_tid = :field_data_field_term_type_field_term_type_tid )
In the prepared query is replaced with
AND (field_data_field_term_type.field_term_type_tid = :L#2253 )
And the binded array has the following args:
Array (
[:db_condition_placeholder_0] => 1
[:db_condition_placeholder_1] => article
[:db_condition_placeholder_2] => en
[:db_condition_placeholder_3] => 1
[:field_data_field_term_type_field_term_type_tid] => test123
[:views_join_condition_0] => node
[:views_join_condition_1] => 0
)
So :L#2253 does not exist in the binded array keys
Comment #8
arrancia commentedSo in short changing # is not going to fix this bug, already tried it
Comment #9
aaaristo commentedwow.. ok, so what about cleanupArgs? in database.inc.. this function can change the key of the args array..
and it is already called by the query() function ... right?
Comment #10
arrancia commentedI didn't noticed that function that's why i asked you maybe you know some better issue than implementing all bind functions :D and you did :D i'll create patch now and test it
Comment #11
miopa commentedAny progress on this?
Comment #12
aaaristo commentedfixed in 1.9
Comment #13
miopa commentedI still have the issue.
To reproduce: enable taxonomy term view, edit, try preview for some term.
Comment #14
aaaristo commentedok, i got an error:
but is different from the one oshman was reporting... Here the problem is not a long identifier but the fact that db_condition_placeholder_0_0 is passed instead of db_condition_placeholder_1... don't know if it is a views or core or oracle bug actually... i've to dig deeper...
Comment #15
cmurph commentedI'm getting the same type of error (I originally posted this message: http://drupal.org/node/1300442 , but found out that this error here is probably the same as what I've been having):
It appears the wrong identifier is being put in via the Oracle driver. Instead of "db_condition_placeholder_0" being utilized, it utilized "db_condition_placeholder_1" in the select instead.
e.g. - If I add another condition to the db_select, here is what we get:
In this example, we are using only the ":db_condition_placeholder_0" and not both that one and ":db_condition_placeholder_1" which then gives us an error.
Anything I can do to help fix this?
This is the only thing holding me back with getting my site up and running.
Thanks!
Comment #16
aaaristo commentedcan u post the php code that is producing this behavior?
Comment #17
cmurph commentedHere is the PHP:
Comment #18
aaaristo commentedif you comment out the SelectQuery_oracle.__toString() method in the select.inc it work better?
Comment #19
cmurph commentedNo, I still get the same error
Comment #20
aaaristo commentedyou should try to investigate where the placeholder for the query is changed from _0 to _1... probably in the core on the compile method of the condition.... the oracle driver does not build those placeholders so the error must be somewhere in the core.. may be some assumption is made that work with mysql and not with oracle... No time actually to look at it.
Comment #21
cmurph commentedGotcha, I'll investigate that and let you know.
Thanks!
Comment #22
sionescu commentedThis occurs with dynamic queries that have conditions on multiple sub-queries.
I believe it's a core 7.8 issue or generated by the way drivers are written for 7.8.
The compile method is called twice, the first time around the placeholders are not colliding, the second time around it's called from select.inc __toString and seems to be redundant.
I removed the two call occurrences to compile and got rid of the collision. Can one of the maintainers please confirm that this is not affecting other functionality?
Thanks
Comment #23
sionescu commentedComment #24
aaaristo commentedi'm going to run simpletests on it...
Comment #25
sionescu commentedThank you,
calling __toString before execute is broken, but that seems to be broken anyway in Drupal 7.8:
Comment #26
cmurph commentedThat fixed my error I was getting.
Thanks Sergiu!
Comment #27
cmurph commentedIt worked for the initial problem, but then we get the error that Sergiu was describing.
Any way to get around that?
Thanks!
Comment #28
sionescu commentedCa you please post the callstack for this error?
I need to see what is calling __toString.
Do you get the error without the patch? I suspect that you are in the view UI and have a query that doesn't return any data, it will then try to do a __toString and print your query.
Comment #29
cmurph commentedI'm not sure how to get the callstack for the error, since I really don't get anything back.
I had put your patch into Select.inc, and was testing out another install of Drupal. That is when it bombed out, when I tried to setup Drupal via install.php.
Once I took out the patch, Drupal installed fine. However, the illegal variable name/number error still comes up as expected (without the patch).
Let me know if I can provide anymore information to help.
Thanks
Comment #30
sneyerst commentedI tested the patch file provided by sionescu and I can confirm that the error is gone now (not for Oracle, but SQL Server, see: http://drupal.org/node/1286792). After some first initial tests, it seems like all is working fine.
Comment #31
sionescu commentedTom,
Is it causing the __toString issue with the SQL Server driver?
Comment #32
sionescu commentedSome Database conditions may not be precompiled so we check and compile only if required.
This also fixes the __toString() issue.
I think that this could be the final fix, can you please re-validate this?
Comment #33
sneyerst commentedSergiu,
I haven't been able to invoke the __toString error with the sqlsrv-driver. At this moment, I applied your latest patch and it seems to do the trick also (tested on 2 different websites, both with the sqlsrv driver).
Is there a reason for checking wether the 'where'-clause is compiled in the having-section?
Comment #34
sionescu commentedGood catch there,
it was supposed to be $this->having->compiled().
I didn't get to test the having condition against these cases.
Thanks!
Comment #35
sneyerst commentedThought so :-). As far as I have seen already, is your patch the resolution for this problem. Thank you!
Perhaps some more reviewing is needed, since I am not familiarised with the way the Drupal database layer works.
Comment #36
sionescu commentedIdeally someone that worked at the Drupal core database layer could take a look at this - as this issue was not present with Drupal 7.7. They may come up with a different solution to the underlying problem.
Until then i hope this fixes most of the issues although it's not so elegant:
If you take a look at the compile() method is does check to see if the query has changed:
and
So it's the second half of that first condition that seems to cause the problems.
Comment #37
aaaristo commentedreleasing it in 1.10