Repository: vertica/vertica-python

Issue:
Parametized queries & tuple issue
Hello!

We ran into some issues with the last release of the package.
I've seen that there were some changes for parametized queries that break some of our work.
It seems that we now can't execute queries with tuple parameters.

For instance, this dumb example
```
with conn.cursor() as curs:
    curs.execute("SELECT %s in %s", (1, (1,2,3)))
    for row in curs.iterate():
        print(row)
```
was running successfully until `0.10.2`, but not working with `0.10.3`. We get the following issue: `TypeError: Cannot convert <class 'tuple'> type object to an SQL string`

Sorry if this is an expected behavior of the last release :)
Have a nice day!

Discussion:

Patch:
diff --git a/vertica_python/vertica/cursor.py b/vertica_python/vertica/cursor.py
index 77b7184..7af4db6 100644
--- a/vertica_python/vertica/cursor.py
+++ b/vertica_python/vertica/cursor.py
@@ -519,6 +519,11 @@ class Cursor(object):
             return self.format_quote(as_text(py_obj), is_copy_data)
         elif isinstance(py_obj, (integer_types, float, Decimal)):
             return str(py_obj)
+        elif isinstance(py_obj, tuple):  # tuple and namedtuple
+            elements = [None] * len(py_obj)
+            for i in range(len(py_obj)):
+                elements[i] = self.object_to_string(py_obj[i], is_copy_data)
+            return "(" + ",".join(elements) + ")"
         elif isinstance(py_obj, (datetime.datetime, datetime.date, datetime.time, UUID)):
             return self.format_quote(as_text(str(py_obj)), is_copy_data)
         else:


Test patch:
diff --git a/vertica_python/tests/unit_tests/test_sql_literal.py b/vertica_python/tests/unit_tests/test_sql_literal.py
index ab51faa..b4752cd 100644
--- a/vertica_python/tests/unit_tests/test_sql_literal.py
+++ b/vertica_python/tests/unit_tests/test_sql_literal.py
@@ -14,6 +14,7 @@
 
 from __future__ import print_function, division, absolute_import
 
+from collections import namedtuple
 from decimal import Decimal
 from uuid import UUID
 import datetime
@@ -48,6 +49,14 @@ class SqlLiteralTestCase(VerticaPythonUnitTestCase):
         # String
         self.assertEqual(cursor.object_to_sql_literal(u"string'1"), "'string''1'")
         self.assertEqual(cursor.object_to_sql_literal(b"string'1"), "'string''1'")
+        # Tuple and namedtuple
+        self.assertEqual(cursor.object_to_sql_literal(
+            (123, u"string'1", None)), "(123,'string''1',NULL)")
+        self.assertEqual(cursor.object_to_sql_literal(
+            ((1, u"a"), (2, u"b"), (3, u"c"))), "((1,'a'),(2,'b'),(3,'c'))")
+        Point = namedtuple('Point', ['x', 'y', 'z'])
+        p = Point(x=11, y=22, z=33)
+        self.assertEqual(cursor.object_to_sql_literal(p), "(11,22,33)")
 
     def test_register_adapters(self):
         class Point(object):