Skip to content

Commit d263fb3

Browse files
author
Elliot Boschwitz
authored
Fixed bug which caused some queries with semicolons to crash (#425)
* Remove rstrip of semicolon in mssqlcliclient * Client and non-interactive tests added
1 parent 77de35f commit d263fb3

File tree

5 files changed

+108
-3
lines changed

5 files changed

+108
-3
lines changed

mssqlcli/mssqlcliclient.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def execute_query(self, query):
106106
else:
107107
for single_query in sqlparse.split(query):
108108
# Remove spaces, EOL and semi-colons from end
109-
single_query = single_query.strip().rstrip(';')
109+
single_query = single_query.strip()
110110
if single_query:
111111
for rows, columns, status, statement, is_error \
112112
in self._execute_query(single_query):

tests/test_mssqlcliclient.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
create_test_db,
1313
clean_up_test_db,
1414
shutdown,
15-
random_str
15+
random_str,
16+
get_io_paths,
17+
get_file_contents
1618
)
1719

1820

@@ -240,7 +242,20 @@ def test_mssqlcliclient_multiple_statement(client, query_str, rows_outputted):
240242
for (i, (rows, _, _, query_executed, is_error)) in \
241243
enumerate(client.execute_query(query_str)):
242244

243-
queries = query_str.split(';')
245+
queries = ["{};".format(query) for query in query_str.split(';')]
244246
assert query_executed == queries[i].strip()
245247
assert len(rows) == rows_outputted[i]
246248
assert (is_error and len(rows) == 0) or (not is_error)
249+
250+
@staticmethod
251+
def test_mssqlcliclient_multiple_merge(client_with_db):
252+
"""
253+
Tests query with multiple merges. Requires creation of temp db.
254+
"""
255+
file_input, _ = get_io_paths('multiple_merge.txt')
256+
query_input = get_file_contents(file_input)
257+
258+
for rows, _, status, _, is_error in client_with_db.execute_query(query_input):
259+
if is_error:
260+
raise AssertionError("Query execution failed: {}".format(status))
261+
assert () == rows

tests/test_noninteractive_mode.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import pytest
77
from mssqltestutils import (
88
create_mssql_cli,
9+
create_test_db,
10+
clean_up_test_db,
911
random_str,
1012
shutdown,
1113
test_queries,
@@ -80,6 +82,25 @@ def test_long_query(tmp_filepath):
8082
finally:
8183
shutdown(mssqlcli)
8284

85+
@pytest.mark.timeout(300)
86+
def test_multiple_merge(self):
87+
"""
88+
Tests query with multiple merges. Requires creation of temp db.
89+
"""
90+
try:
91+
# create temporary db
92+
db_name = create_test_db()
93+
94+
file_input, file_baseline = get_io_paths('multiple_merge.txt')
95+
text_baseline = get_file_contents(file_baseline)
96+
97+
# test with -i
98+
output_query = self.execute_query_via_subprocess("-i {} -d {}"\
99+
.format(file_input, db_name))
100+
assert output_query == text_baseline
101+
finally:
102+
clean_up_test_db(db_name)
103+
83104
@classmethod
84105
@pytest.mark.timeout(60)
85106
def test_Q_with_i_run(cls):
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Commands completed successfully.
2+
Commands completed successfully.
3+
(4 rows affected)
4+
Commands completed successfully.
5+
Commands completed successfully.
6+
(5 rows affected)
7+
(6 rows affected)
8+
(5 rows affected)
9+
Commands completed successfully.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
drop table if exists dbo.category;
2+
CREATE TABLE dbo.category (
3+
category_id INT PRIMARY KEY,
4+
category_name VARCHAR(255) NOT NULL,
5+
amount DECIMAL(10 , 2 )
6+
);
7+
8+
INSERT INTO dbo.category(category_id, category_name, amount)
9+
VALUES(1,'Children Bicycles',15000),
10+
(2,'Comfort Bicycles',25000),
11+
(3,'Cruisers Bicycles',13000),
12+
(4,'Cyclocross Bicycles',10000);
13+
14+
drop table if exists dbo.category_staging;
15+
CREATE TABLE dbo.category_staging (
16+
category_id INT PRIMARY KEY,
17+
category_name VARCHAR(255) NOT NULL,
18+
amount DECIMAL(10 , 2 )
19+
);
20+
21+
INSERT INTO dbo.category_staging(category_id, category_name, amount)
22+
VALUES(1,'Children Bicycles',15000),
23+
(3,'Cruisers Bicycles',13000),
24+
(4,'Cyclocross Bicycles',20000),
25+
(5,'Electric Bikes',10000),
26+
(6,'Mountain Bikes',10000);
27+
28+
29+
go
30+
31+
--Do the merge
32+
MERGE dbo.category t
33+
USING dbo.category_staging s
34+
ON (s.category_id = t.category_id)
35+
WHEN MATCHED
36+
THEN UPDATE SET
37+
t.category_name = s.category_name,
38+
t.amount = s.amount
39+
WHEN NOT MATCHED BY TARGET
40+
THEN INSERT (category_id, category_name, amount)
41+
VALUES (s.category_id, s.category_name, s.amount)
42+
WHEN NOT MATCHED BY SOURCE
43+
THEN DELETE;
44+
45+
go
46+
47+
--Do the exact same statement (cut/pasted)
48+
MERGE dbo.category t
49+
USING dbo.category_staging s
50+
ON (s.category_id = t.category_id)
51+
WHEN MATCHED
52+
THEN UPDATE SET
53+
t.category_name = s.category_name,
54+
t.amount = s.amount
55+
WHEN NOT MATCHED BY TARGET
56+
THEN INSERT (category_id, category_name, amount)
57+
VALUES (s.category_id, s.category_name, s.amount)
58+
WHEN NOT MATCHED BY SOURCE
59+
THEN DELETE;
60+
go

0 commit comments

Comments
 (0)