[Django] #20785: [oracle] ORA-01425: escape character must be character string of length 1

40 views
Skip to first unread message

Django

unread,
Jul 22, 2013, 5:27:24 AM7/22/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
----------------------------------------------+------------------------
Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.6-beta-1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+------------------------
Upgrading from 1.5 to 1.6 beta this error, which was fixed in #14149 crops
up again. The simple fix is to add DatabaseError to the try/except block
that wraps the query to test for Oracle operators when creating the
connection. I'm on Python 2.7.3 cxOracle 5.1.2.

--
Ticket URL: <https://code.djangoproject.com/ticket/20785>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 22, 2013, 6:36:27 AM7/22/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by aaugustin):

* needs_better_patch: => 0
* severity: Normal => Release blocker
* needs_tests: => 0
* needs_docs: => 0


Comment:

Marking as a release blocker since the report says it's a regression.

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:1>

Django

unread,
Jul 22, 2013, 12:26:05 PM7/22/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by shai):

What Oracle version are you using?

(obviously, starting connections on Oracle works for most of us --
further, master is continuously tested against Oracle, and ATM the Oracle
backend is essentially the same in master and 1.6b1).

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:2>

Django

unread,
Jul 22, 2013, 12:26:18 PM7/22/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by shai):

* cc: shai@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:3>

Django

unread,
Jul 23, 2013, 5:27:28 AM7/23/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by anonymous):

Shai, of course I imagine I'm not the only one using Oracle, that's why
the error threw me off guard. :)

Here is the output of "select * from product_component_version"

[('NLSRTL ', '10.2.0.2.0', 'Production'),
('Oracle Database 10g Enterprise Edition ', '10.2.0.2.0', 'Prod'),
('PL/SQL ', '10.2.0.2.0', 'Production'),
('TNS for Linux: ', '10.2.0.2.0', 'Production')]

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:4>

Django

unread,
Jul 24, 2013, 8:58:05 PM7/24/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by shai):

I suspect this is a unicode-vs-oracle-10 problem, similar to #20292
(although that one shows up already with Django 1.5.1).

If this is indeed the case, applying the attached oracle-10.patch should
probably fix both problems; I have no way to test this myself, so I'm
asking you to test. I only tested on master against Oracle 11, to see on a
preliminary level that it doesn't break things; if it helps, I'll test it
more thoroughly (but still, only against Oracle 11; that's what I have).

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:5>

Django

unread,
Jul 25, 2013, 5:42:40 AM7/25/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ludo):

The patch does not work (and btw line numbers are relative to master, they
are different for the second block in 1.6.x).

What I don't understand is why use `utils.DatabaseError` -- which does not
work to trap the exception -- where you have a perfectly working local
`DatabaseError` which works as intended.

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:6>

Django

unread,
Jul 25, 2013, 8:40:46 AM7/25/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by shai):

We could use the DatabaseError, but I think that would be the wrong fix --
as far as I understand, the operators this code checks for are available
on Oracle 10, so you should only get the exception on Oracle 9. If the
exception is thrown and caught, you will be limited in your "like" queries
(contains, startswith, etc).

That's why I'm trying to fix it from the other direction -- preventing the
exception from being raised in the first place.

And yes, I made the change in master -- the oracle backend on 1.6 is not
significantly different, so I take the liberty to work where it is more
convenient for me; the patch uses different line numbers, but does apply
cleanly with `patch -p1 < oracle-10.patch` executed at the django root.

Is there any chance for you to test this on 10.2.0.5 ? I believe that
users of that version do not encounter this problem (only #20292)

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:7>

Django

unread,
Jul 25, 2013, 11:05:14 AM7/25/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ludo):

Yes I know it applies cleanly, I was just nitpicking. :)

Unfortunately I have no way to test against 10.2.0.5...

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:8>

Django

unread,
Jul 25, 2013, 5:19:04 PM7/25/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------

Reporter: ludo | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ludo):

Replying to [comment:7 shai]:


> We could use the DatabaseError, but I think that would be the wrong fix
-- as far as I understand, the operators this code checks for are
available on Oracle 10, so you should only get the exception on Oracle 9.
If the exception is thrown and caught, you will be limited in your "like"
queries (contains, startswith, etc).

Might be there are two fixes needed: one to be able to use the right
operators, and one to actually trap DatabaseError if it gets raised (which
it shouldn't as per the first needed fix, but anyway...).

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:9>

Django

unread,
Jul 29, 2013, 8:29:02 PM7/29/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------
Reporter: ludo | Owner: shai
Type: Bug | Status: assigned

Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by shai):

* owner: nobody => shai
* status: new => assigned
* stage: Unreviewed => Accepted


Comment:

Having read the related tickets and discussions (and code) more carefully,
it seems I was a little confused, and your solution appears correct --
except for the part that `utils.DatabaseError` is actually not necessary
at all there.

The regression was introduced in
[59a352087591a26023412cbcb830cd1d34fc9b99] which refactored the wrapping
of database exceptions -- and made it so that this code runs with a "bare"
(non-wrapped) cursor.

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:10>

Django

unread,
Jul 29, 2013, 8:55:55 PM7/29/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------
Reporter: ludo | Owner: shai
Type: Bug | Status: closed

Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Shai Berger <shai@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"6ed579e7eb6e1eda3dd1b0afb306d58b9498bfa0"]:
{{{
#!CommitTicketReference repository=""
revision="6ed579e7eb6e1eda3dd1b0afb306d58b9498bfa0"
Fixed #20785 -- Corrected exception caught for Oracle LIKE operator
detection

The code that tests to see which LIKE expressions to use now runs
using non-error-wrapped cursor, so cx_Oracle exceptions need to be caught
rather than Django DatabaseErrors.

Thanks Trac user ludo for report and initial patch.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:11>

Django

unread,
Jul 29, 2013, 8:56:09 PM7/29/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------
Reporter: ludo | Owner: shai
Type: Bug | Status: closed
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Shai Berger <shai@…>):

In [changeset:"17e632929cdf9575f538c1f98379adac8698c288"]:
{{{
#!CommitTicketReference repository=""
revision="17e632929cdf9575f538c1f98379adac8698c288"
[1.6.x] Fixed #20785 -- Corrected exception caught for Oracle LIKE
operator detection

The code that tests to see which LIKE expressions to use now runs
using non-error-wrapped cursor, so cx_Oracle exceptions need to be caught
rather than Django DatabaseErrors.

Thanks Trac user ludo for report and initial patch.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:12>

Django

unread,
Jul 30, 2013, 2:33:25 AM7/30/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------
Reporter: ludo | Owner: shai
Type: Bug | Status: closed
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by aaugustin):

Thank you for fixing my mess, and sorry.

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:13>

Django

unread,
Jul 31, 2013, 7:19:12 AM7/31/13
to django-...@googlegroups.com
#20785: [oracle] ORA-01425: escape character must be character string of length 1
-------------------------------------+-------------------------------------
Reporter: ludo | Owner: shai
Type: Bug | Status: closed
Component: Database layer | Version:
(models, ORM) | 1.6-beta-1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by shai):

For the record, I don't think there was any reasonable way for you to
avoid this, nothing you should apologize for. At some point I may try to
get to the bottom of this and set up a test to validate it, but since Ian
already dug into this a few years ago and came up with not-much, I'm not
making it a high priority.

--
Ticket URL: <https://code.djangoproject.com/ticket/20785#comment:14>

Reply all
Reply to author
Forward
0 new messages