Skip to content

Commit a49f7e1

Browse files
committed
Fix #111 - support semicolons in values in SQL script files
1 parent 7ff91a6 commit a49f7e1

File tree

5 files changed

+59
-5
lines changed

5 files changed

+59
-5
lines changed

src/DatabaseLibrary/query.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,14 @@ def execute_sql_script(self, sqlScriptFileName, sansTran=False):
272272
# semicolons inside the line? use them to separate statements
273273
# ... but not if they are inside a begin/end block (aka. statements group)
274274
sqlFragments = line.split(';')
275-
276275
# no semicolons
277276
if len(sqlFragments) == 1:
278277
current_statement += line + ' '
279278
continue
280-
279+
quotes = 0
281280
# "select * from person;" -> ["select..", ""]
282281
for sqlFragment in sqlFragments:
283-
sqlFragment = sqlFragment.strip()
284-
if len(sqlFragment) == 0:
282+
if len(sqlFragment.strip()) == 0:
285283
continue
286284
if inside_statements_group:
287285
# if statements inside a begin/end block have semicolns,
@@ -291,10 +289,20 @@ def execute_sql_script(self, sqlScriptFileName, sansTran=False):
291289
inside_statements_group = False
292290
elif sqlFragment.lower().startswith("begin"):
293291
inside_statements_group = True
292+
293+
# check if the semicolon is a part of the value (quoted string)
294+
quotes += sqlFragment.count("'")
295+
quotes -= sqlFragment.count("\\'")
296+
quotes -= sqlFragment.count("''")
297+
inside_quoted_string = quotes % 2 != 0
298+
if inside_quoted_string:
299+
sqlFragment += ";" # restore the semicolon
300+
294301
current_statement += sqlFragment
295-
if not inside_statements_group:
302+
if not inside_statements_group and not inside_quoted_string:
296303
statements_to_execute.append(current_statement.strip())
297304
current_statement = ''
305+
quotes = 0
298306

299307
current_statement = current_statement.strip()
300308
if len(current_statement) != 0:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
INSERT INTO person VALUES(5, 'Miles', 'O''Brian');
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
INSERT INTO person VALUES(3, 'Hello; world', 'Another; value');
2+
INSERT INTO person VALUES(4, 'May the Force; ', 'be with you;');
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
INSERT INTO person VALUES(6, 'Julian', 'Bashir'); INSERT INTO person VALUES(7, 'Jadzia', 'Dax');
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
*** Settings ***
2+
Resource ../../resources/common.resource
3+
4+
Suite Setup Connect To DB
5+
Suite Teardown Disconnect From Database
6+
Test Setup Create Person Table
7+
Test Teardown Drop Tables Person And Foobar
8+
9+
10+
*** Test Cases ***
11+
Semicolons As Statement Separators In One Line
12+
Run SQL Script File statements_in_one_line
13+
${sql}= Catenate select * from person
14+
... where id=6 or id=7
15+
${results}= Query ${sql}
16+
Length Should Be ${results} 2
17+
Should Be Equal As Strings ${results}[0] (6, 'Julian', 'Bashir')
18+
Should Be Equal As Strings ${results}[1] (7, 'Jadzia', 'Dax')
19+
20+
Semicolons In Values
21+
Run SQL Script File semicolons_in_values
22+
${sql}= Catenate select * from person
23+
... where id=3 or id=4
24+
${results}= Query ${sql}
25+
Length Should Be ${results} 2
26+
Should Be Equal As Strings ${results}[0] (3, 'Hello; world', 'Another; value')
27+
Should Be Equal As Strings ${results}[1] (4, 'May the Force; ', 'be with you;')
28+
29+
Semicolons And Quotes In Values
30+
Run SQL Script File semicolons_and_quotes_in_values
31+
${sql}= Catenate select * from person
32+
... where id=5
33+
${results}= Query ${sql}
34+
Length Should Be ${results} 1
35+
Should Be Equal As Strings ${results}[0] (5, 'Miles', "O'Brian")
36+
37+
38+
*** Keywords ***
39+
Run SQL Script File
40+
[Arguments] ${File Name}
41+
${Script files dir}= Set Variable ${CURDIR}/../../resources/script_file_tests
42+
Execute Sql Script ${Script files dir}/${File Name}.sql

0 commit comments

Comments
 (0)