Skip to content

Commit 78c8308

Browse files
Raise exceptions when strings and identifiers are not terminated.
1 parent 16f3e9f commit 78c8308

File tree

4 files changed

+22
-5
lines changed

4 files changed

+22
-5
lines changed

doc/src/release_notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ Common Changes
3030
:meth:`Cursor.setinputsizes()` with at least one of the values supplied as
3131
``None``
3232
(`issue 217 <https://github.com/oracle/python-oracledb/issues/217>`__).
33+
#) SQL statement parsing now raises ``DPY-2041: missing ending quote (') in
34+
string`` or ``DPY-2042: missing ending quote (") in identifier`` for
35+
statements with the noted invalid syntax. Previously, thick mode gave
36+
``ORA-1756`` or ``ORA-1740``, respectively, while thin mode did not throw
37+
an error.
3338

3439

3540
oracledb 1.4.0 (August 2023)

src/oracledb/errors.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ def _raise_from_string(exc_type: Exception, message: str) -> None:
188188
ERR_INVALID_COLL_INDEX_GET = 2038
189189
ERR_INVALID_COLL_INDEX_SET = 2039
190190
ERR_EXECUTE_MODE_ONLY_FOR_DML = 2040
191+
ERR_MISSING_QUOTE_IN_STRING = 2041
192+
ERR_MISSING_QUOTE_IN_IDENTIFIER = 2042
191193

192194
# error numbers that result in NotSupportedError
193195
ERR_TIME_NOT_SUPPORTED = 3000
@@ -267,6 +269,8 @@ def _raise_from_string(exc_type: Exception, message: str) -> None:
267269
28: ERR_CONNECTION_CLOSED,
268270
600: ERR_CONNECTION_CLOSED,
269271
1005: ERR_NO_CREDENTIALS,
272+
1740: ERR_MISSING_QUOTE_IN_IDENTIFIER,
273+
1756: ERR_MISSING_QUOTE_IN_STRING,
270274
22165: (ERR_INVALID_COLL_INDEX_SET,
271275
r'index \[(?P<index>\d+)\] must be in the range of '
272276
r'\[(?P<min_index>\d+)\] to \[(?P<max_index>\d+)\]'),
@@ -428,6 +432,10 @@ def _raise_from_string(exc_type: Exception, message: str) -> None:
428432
ERR_MISSING_BIND_VALUE:
429433
'a bind variable replacement value for placeholder ":{name}" was '
430434
'not provided',
435+
ERR_MISSING_QUOTE_IN_IDENTIFIER:
436+
'missing ending quote (") in identifier',
437+
ERR_MISSING_QUOTE_IN_STRING:
438+
"missing ending quote (') in string",
431439
ERR_MISSING_TYPE_NAME_FOR_OBJECT_VAR:
432440
'no object type specified for object variable',
433441
ERR_MIXED_ELEMENT_TYPES:

src/oracledb/impl/thin/statement.pyx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,11 @@ cdef class Parser:
174174
exiting_qstring = True
175175
elif exiting_qstring:
176176
if ch == "'":
177-
break
177+
return 0
178178
elif ch != sep:
179179
exiting_qstring = False
180180
self.pos += 1
181+
errors._raise_err(errors.ERR_MISSING_QUOTE_IN_STRING)
181182

182183
cdef int _parse_quoted_string(self, Py_UCS4 sep) except -1:
183184
"""
@@ -189,8 +190,12 @@ cdef class Parser:
189190
while self.pos <= self.max_pos:
190191
ch = cpython.PyUnicode_READ(self.sql_kind, self.sql_data, self.pos)
191192
if ch == sep:
192-
break
193+
return 0
193194
self.pos += 1
195+
if sep == "'":
196+
errors._raise_err(errors.ERR_MISSING_QUOTE_IN_STRING)
197+
else:
198+
errors._raise_err(errors.ERR_MISSING_QUOTE_IN_IDENTIFIER)
194199

195200
cdef int _parse_single_line_comment(self) except -1:
196201
"""

tests/test_3900_cursor_execute.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,8 @@ def test_3906_execute_and_modify_array_size(self):
8787
def test_3907_bad_execute(self):
8888
"3907 - test that subsequent executes succeed after bad execute"
8989
sql = "begin raise_application_error(-20000, 'this); end;"
90-
self.assertRaisesRegex(oracledb.DatabaseError,
91-
"^ORA-06550:|^ORA-01756:", self.cursor.execute,
92-
sql)
90+
self.assertRaisesRegex(oracledb.DatabaseError, "^DPY-2041:",
91+
self.cursor.execute, sql)
9392
self.cursor.execute("begin null; end;")
9493

9594
def test_3908_fetch_after_bad_execute(self):

0 commit comments

Comments
 (0)