164 lines
6.7 KiB
Python
164 lines
6.7 KiB
Python
#------------------------------------------------------------------------------
|
|
# Copyright (c) 2023, Oracle and/or its affiliates.
|
|
#
|
|
# This software is dual-licensed to you under the Universal Permissive License
|
|
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
|
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
|
# either license.
|
|
#
|
|
# If you elect to accept the software under the Apache License, Version 2.0,
|
|
# the following applies:
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#------------------------------------------------------------------------------
|
|
|
|
"""
|
|
5200 - Module for testing the SQL parser.
|
|
"""
|
|
|
|
import oracledb
|
|
import test_env
|
|
|
|
class TestCase(test_env.BaseTestCase):
|
|
|
|
def test_5200_single_line_comment(self):
|
|
"5200 - single line comment"
|
|
self.cursor.prepare("""--begin :value2 := :a + :b + :c +:a +3; end;
|
|
begin :value2 := :a + :c +3; end;""")
|
|
self.assertEqual(self.cursor.bindnames(), ["VALUE2", "A", "C"])
|
|
|
|
def test_5201_multiple_line_comment(self):
|
|
"5201 - multiple line comment"
|
|
self.cursor.prepare("""/*--select * from :a where :a = 1
|
|
select * from table_names where :a = 1*/
|
|
select :table_name, :value from dual""")
|
|
self.assertEqual(self.cursor.bindnames(), ["TABLE_NAME", "VALUE"])
|
|
|
|
def test_5202_constant_strings(self):
|
|
"5202 - constant strings"
|
|
statement = """
|
|
begin
|
|
:value := to_date('20021231 12:31:00', :format);
|
|
end;"""
|
|
self.cursor.prepare(statement)
|
|
self.assertEqual(self.cursor.bindnames(), ["VALUE", "FORMAT"])
|
|
|
|
def test_5203_multiple_division_operators(self):
|
|
"5203 - multiple division operators"
|
|
self.cursor.prepare("""
|
|
select :a / :b, :c / :d
|
|
from dual""")
|
|
self.assertEqual(self.cursor.bindnames(), ["A", "B", "C", "D"])
|
|
|
|
def test_5204_opening_parentheses(self):
|
|
"5204 - starting with parentheses"
|
|
sql = "(select :a from dual) union (select :b from dual)"
|
|
self.cursor.prepare(sql)
|
|
self.assertEqual(self.cursor.bindnames(), ["A", "B"])
|
|
|
|
def test_5205_invalid_quoted_bind(self):
|
|
"5205 - invalid quoted bind"
|
|
sql = 'select ":test", :a from dual'
|
|
self.cursor.prepare(sql)
|
|
self.assertEqual(self.cursor.bindnames(), ["A"])
|
|
|
|
def test_5206_non_ascii_bind_name(self):
|
|
"5206 - non-ascii character in the bind name"
|
|
sql = 'select :méil$ from dual'
|
|
self.cursor.prepare(sql)
|
|
self.assertEqual(self.cursor.bindnames(), ['MÉIL$'])
|
|
|
|
def test_5207_various_quoted_binds(self):
|
|
"5207 - various quoted bind names"
|
|
tests = [
|
|
('select :"percent%" from dual', ["percent%"]),
|
|
('select : "q?marks" from dual', ["q?marks"]),
|
|
('select :"percent%(ens)yah" from dual', ["percent%(ens)yah"]),
|
|
('select : "per % cent" from dual', ["per % cent"]),
|
|
('select :"per cent" from dual', ["per cent"]),
|
|
('select :"par(ens)" from dual', ["par(ens)"]),
|
|
('select :"more/slashes" from dual', ["more/slashes"]),
|
|
('select :"%percent" from dual', ["%percent"]),
|
|
('select :"/slashes/" from dual', ["/slashes/"]),
|
|
('select :"1col:on" from dual', ["1col:on"]),
|
|
('select :"col:ons" from dual', ["col:ons"]),
|
|
('select :"more :: %colons%" from dual', ["more :: %colons%"]),
|
|
('select :"more/slashes" from dual', ["more/slashes"]),
|
|
('select :"spaces % spaces" from dual', ["spaces % spaces"]),
|
|
('select "col:nns", :"col:ons", :id from dual', ["col:ons", "ID"])
|
|
]
|
|
for sql, expected in tests:
|
|
with self.subTest(sql=sql, expected=expected):
|
|
self.cursor.prepare(sql)
|
|
self.assertEqual(self.cursor.bindnames(), expected)
|
|
|
|
def test_5208_sql_with_quoted_identifiers_and_strings(self):
|
|
"5208 - sql contaiting quoted identifiers and strings"
|
|
sql = 'select "/*_value1" + : "VaLue_2" + :"*/3VALUE" from dual'
|
|
self.cursor.prepare(sql)
|
|
self.assertEqual(self.cursor.bindnames(), ["VaLue_2", "*/3VALUE"])
|
|
|
|
def test_5209_single_strings(self):
|
|
"5209 - statement containing simple strings"
|
|
sql = '''select '"string_1"', :bind_1, ':string_2' from dual'''
|
|
self.cursor.prepare(sql)
|
|
self.assertEqual(self.cursor.bindnames(), ['BIND_1'])
|
|
|
|
def test_5210_binds_between_comment_blocks(self):
|
|
"5210 - bind variables between comment blocks"
|
|
self.cursor.prepare("""
|
|
select
|
|
/* comment 1 with /* */
|
|
:a,
|
|
/* comment 2 with another /* */
|
|
:b
|
|
/* comment 3 * * * / */,
|
|
:c
|
|
from dual""")
|
|
self.assertEqual(self.cursor.bindnames(), ["A", "B", "C"])
|
|
|
|
def test_5211_binds_between_qstrings(self):
|
|
"5211 - bind variables between q-strings"
|
|
self.cursor.prepare("""
|
|
select
|
|
:a,
|
|
q'{This contains ' and " and : just fine}',
|
|
:b,
|
|
q'[This contains ' and " and : just fine]',
|
|
:c,
|
|
q'<This contains ' and " and : just fine>',
|
|
:d,
|
|
q'(This contains ' and " and : just fine)',
|
|
:e,
|
|
q'$This contains ' and " and : just fine$',
|
|
:f
|
|
from dual""")
|
|
self.assertEqual(self.cursor.bindnames(),
|
|
["A", "B", "C", "D", "E", "F"])
|
|
|
|
def test_5212_binds_between_json_constants(self):
|
|
"5212 - bind variables between JSON constants"
|
|
self.cursor.prepare("""
|
|
select
|
|
json_object('foo':dummy),
|
|
:bv1,
|
|
json_object('foo'::bv2),
|
|
:bv3,
|
|
json { 'key1': 57, 'key2' : 58 },
|
|
:bv4
|
|
from dual""")
|
|
self.assertEqual(self.cursor.bindnames(), ["BV1", "BV2", "BV3", "BV4"])
|
|
|
|
if __name__ == "__main__":
|
|
test_env.run_test_cases()
|