Repository: kayak/pypika (python)

Issue:
How to insert Array value into field?
For example
```sql
CREATE TABLE public.catalog (
   id           SERIAL PRIMARY KEY 
  ,name         VARCHAR(100) NOT NULL
  ,price        decimal(6,2) NOT NULL
  ,retail_price decimal(6,2) NOT NULL
  ,code         VARCHAR(100) NOT NULL
  ,property_values   integer[]
  ,images	VARCHAR[]
);

```
```python
    sql = str(
        pypika.PostgreSQLQuery
        .into(pypika.Table('catalog', schema='public'))
        .insert(
            (
               1,
               'test',
               '0.00',
               '0.00',
               'test',
               [1, 2, 3],
               ["some", "cool"],
            )
        )
    )
```

Pull request description:
Add support for array types
Fixes #143

Changed the SQL output for python array types to be arrays with square brackets

Previous to this change, python list type arguments were converted to a tuple type. Now, there is support for both tuples and arrays, and the appropriate data type must be used.

Patch:
diff --git a/pypika/terms.py b/pypika/terms.py
index 193203f..a0d1fc4 100644
--- a/pypika/terms.py
+++ b/pypika/terms.py
@@ -64,7 +64,9 @@ class Term(object):
             return val
         if val is None:
             return NullValue()
-        if isinstance(val, (list, tuple)):
+        if isinstance(val, list):
+            return Array(*val)
+        if isinstance(val, tuple):
             return Tuple(*val)
 
         return ValueWrapper(val)
@@ -344,8 +346,16 @@ class Tuple(Term):
 
     def get_sql(self, **kwargs):
         return '({})'.format(
-            ','.join(term.get_sql(**kwargs)
-                     for term in self.values)
+              ','.join(term.get_sql(**kwargs)
+                       for term in self.values)
+        )
+
+
+class Array(Tuple):
+    def get_sql(self, **kwargs):
+        return '[{}]'.format(
+              ','.join(term.get_sql(**kwargs)
+                       for term in self.values)
         )
 
 
@@ -996,4 +1006,4 @@ class Psuedocolumn(Term):
         self.name = name
 
     def to_sql(self, **kwargs):
-        return self.name
\ No newline at end of file
+        return self.name


Test patch:
diff --git a/pypika/tests/test_inserts.py b/pypika/tests/test_inserts.py
index 615ed92..b863c3c 100644
--- a/pypika/tests/test_inserts.py
+++ b/pypika/tests/test_inserts.py
@@ -36,31 +36,38 @@ class InsertIntoTests(unittest.TestCase):
 
         self.assertEqual('INSERT INTO "abc" VALUES (1),(2)', str(query))
 
-    def test_insert_array_value(self):
-        query = Query.into(self.table_abc).insert((1,), )
+    def test_insert_single_row_with_array_value(self):
+        query = Query.into(self.table_abc).insert(1, ['a', 'b', 'c'])
 
-        self.assertEqual('INSERT INTO "abc" VALUES (1),(2)', str(query))
+        self.assertEqual('INSERT INTO "abc" VALUES (1,[\'a\',\'b\',\'c\'])', str(query))
+
+    def test_insert_multiple_rows_with_array_value(self):
+        query = Query.into(self.table_abc).insert((1, ['a', 'b', 'c']),
+                                                  (2, ['c', 'd', 'e']), )
+
+        self.assertEqual('INSERT INTO "abc" '
+                         'VALUES (1,[\'a\',\'b\',\'c\']),(2,[\'c\',\'d\',\'e\'])', str(query))
 
     def test_insert_all_columns(self):
         query = Query.into(self.table_abc).insert(1, 'a', True)
 
         self.assertEqual('INSERT INTO "abc" VALUES (1,\'a\',true)', str(query))
 
-    def test_insert_all_columns_multi_rows_chained(self):
-        query = Query.into(self.table_abc).insert(1, 'a', True).insert(2, 'b', False)
-
-        self.assertEqual('INSERT INTO "abc" VALUES (1,\'a\',true),(2,\'b\',false)', str(query))
-
-    def test_insert_all_columns_single_element_arrays(self):
+    def test_insert_all_columns_single_element(self):
         query = Query.into(self.table_abc).insert((1, 'a', True))
 
         self.assertEqual('INSERT INTO "abc" VALUES (1,\'a\',true)', str(query))
 
-    def test_insert_all_columns_multi_rows_arrays(self):
+    def test_insert_all_columns_multi_rows(self):
         query = Query.into(self.table_abc).insert((1, 'a', True), (2, 'b', False))
 
         self.assertEqual('INSERT INTO "abc" VALUES (1,\'a\',true),(2,\'b\',false)', str(query))
 
+    def test_insert_all_columns_multi_rows_chained(self):
+        query = Query.into(self.table_abc).insert(1, 'a', True).insert(2, 'b', False)
+
+        self.assertEqual('INSERT INTO "abc" VALUES (1,\'a\',true),(2,\'b\',false)', str(query))
+
     def test_insert_all_columns_multi_rows_chained_mixed(self):
         query = Query.into(self.table_abc).insert(
             (1, 'a', True), (2, 'b', False)
@@ -70,12 +77,12 @@ class InsertIntoTests(unittest.TestCase):
                          '(1,\'a\',true),(2,\'b\',false),'
                          '(3,\'c\',true)', str(query))
 
-    def test_insert_all_columns_multi_rows_chained_arrays(self):
-        query = Query.into(self.table_abc).insert(
-            (1, 'a', True), (2, 'b', False)
-        ).insert(
-            (3, 'c', True), (4, 'd', False)
-        )
+    def test_insert_all_columns_multi_rows_chained_multiple_rows(self):
+        query = Query.into(self.table_abc) \
+            .insert((1, 'a', True),
+                    (2, 'b', False)) \
+            .insert((3, 'c', True),
+                    (4, 'd', False))
 
         self.assertEqual('INSERT INTO "abc" VALUES '
                          '(1,\'a\',true),(2,\'b\',false),'
@@ -166,7 +173,7 @@ class PostgresInsertIntoReturningTests(unittest.TestCase):
         self.assertEqual('INSERT INTO "abc" VALUES (1) RETURNING NULL', str(query))
 
     def test_insert_returning_tuple(self):
-        query = PostgreSQLQuery.into(self.table_abc).insert(1).returning([1, 2, 3])
+        query = PostgreSQLQuery.into(self.table_abc).insert(1).returning((1, 2, 3))
 
         self.assertEqual('INSERT INTO "abc" VALUES (1) RETURNING (1,2,3)', str(query))