summaryrefslogtreecommitdiff
path: root/test/dialect/test_postgresql.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/dialect/test_postgresql.py')
-rw-r--r--test/dialect/test_postgresql.py192
1 files changed, 191 insertions, 1 deletions
diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py
index 3be005f36..33753b48f 100644
--- a/test/dialect/test_postgresql.py
+++ b/test/dialect/test_postgresql.py
@@ -13,14 +13,16 @@ from sqlalchemy import Table, Column, select, MetaData, text, Integer, \
PrimaryKeyConstraint, DateTime, tuple_, Float, BigInteger, \
func, literal_column, literal, bindparam, cast, extract, \
SmallInteger, Enum, REAL, update, insert, Index, delete, \
- and_, Date, TypeDecorator, Time, Unicode, Interval, or_
+ and_, Date, TypeDecorator, Time, Unicode, Interval, or_, Text
from sqlalchemy.orm import Session, mapper, aliased
from sqlalchemy import exc, schema, types
from sqlalchemy.dialects.postgresql import base as postgresql
+from sqlalchemy.dialects.postgresql import HSTORE, hstore
from sqlalchemy.util.compat import decimal
from sqlalchemy.testing.util import round_decimal
from sqlalchemy.sql import table, column
import logging
+import re
class SequenceTest(fixtures.TestBase, AssertsCompiledSQL):
@@ -2707,3 +2709,191 @@ class TupleTest(fixtures.TestBase):
).scalar(),
exp
)
+
+
+class HStoreTest(fixtures.TestBase):
+ def _assert_sql(self, construct, expected):
+ dialect = postgresql.dialect()
+ compiled = str(construct.compile(dialect=dialect))
+ compiled = re.sub(r'\s+', ' ', compiled)
+ expected = re.sub(r'\s+', ' ', expected)
+ eq_(compiled, expected)
+
+ def setup(self):
+ metadata = MetaData()
+ self.test_table = Table('test_table', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('hash', HSTORE)
+ )
+ self.hashcol = self.test_table.c.hash
+
+ def _test_where(self, whereclause, expected):
+ stmt = select([self.test_table]).where(whereclause)
+ self._assert_sql(
+ stmt,
+ "SELECT test_table.id, test_table.hash FROM test_table "
+ "WHERE %s" % expected
+ )
+
+ def _test_cols(self, colclause, expected, from_=True):
+ stmt = select([colclause])
+ self._assert_sql(
+ stmt,
+ (
+ "SELECT %s" +
+ (" FROM test_table" if from_ else "")
+ ) % expected
+ )
+
+ def test_where_has_key(self):
+ self._test_where(
+ self.hashcol.has_key('foo'),
+ "test_table.hash ? %(hash_1)s"
+ )
+
+ def test_where_has_all(self):
+ self._test_where(
+ self.hashcol.has_all(postgresql.array(['1', '2'])),
+ "test_table.hash ?& ARRAY[%(param_1)s, %(param_2)s]"
+ )
+
+ def test_where_has_any(self):
+ self._test_where(
+ self.hashcol.has_any(postgresql.array(['1', '2'])),
+ "test_table.hash ?| ARRAY[%(param_1)s, %(param_2)s]"
+ )
+
+ def test_where_defined(self):
+ self._test_where(
+ self.hashcol.defined('foo'),
+ "defined(test_table.hash, %(param_1)s)"
+ )
+
+ def test_where_contains(self):
+ self._test_where(
+ self.hashcol.contains({'foo': '1'}),
+ "test_table.hash @> %(hash_1)s"
+ )
+
+ def test_where_contained_by(self):
+ self._test_where(
+ self.hashcol.contained_by({'foo': '1', 'bar': None}),
+ "test_table.hash <@ %(hash_1)s"
+ )
+
+ def test_where_getitem(self):
+ self._test_where(
+ self.hashcol['bar'] == None,
+ "(test_table.hash -> %(hash_1)s) IS NULL"
+ )
+
+ def test_cols_get(self):
+ self._test_cols(
+ self.hashcol['foo'],
+ "test_table.hash -> %(hash_1)s AS anon_1",
+ True
+ )
+
+ def test_cols_delete_single_key(self):
+ self._test_cols(
+ self.hashcol.delete('foo'),
+ "delete(test_table.hash, %(param_1)s) AS delete_1",
+ True
+ )
+
+ def test_cols_delete_array_of_keys(self):
+ self._test_cols(
+ self.hashcol.delete(postgresql.array(['foo', 'bar'])),
+ ("delete(test_table.hash, ARRAY[%(param_1)s, %(param_2)s]) "
+ "AS delete_1"),
+ True
+ )
+
+ def test_cols_delete_matching_pairs(self):
+ self._test_cols(
+ self.hashcol.delete(hstore('1', '2')),
+ ("delete(test_table.hash, hstore(%(param_1)s, %(param_2)s)) "
+ "AS delete_1"),
+ True
+ )
+
+ def test_cols_slice(self):
+ self._test_cols(
+ self.hashcol.slice(postgresql.array(['1', '2'])),
+ ("slice(test_table.hash, ARRAY[%(param_1)s, %(param_2)s]) "
+ "AS slice_1"),
+ True
+ )
+
+ def test_cols_hstore_pair_text(self):
+ self._test_cols(
+ hstore('foo', '3')['foo'],
+ "hstore(%(param_1)s, %(param_2)s) -> %(hstore_1)s AS anon_1",
+ False
+ )
+
+ def test_cols_hstore_pair_array(self):
+ self._test_cols(
+ hstore(postgresql.array(['1', '2']),
+ postgresql.array(['3', None]))['1'],
+ ("hstore(ARRAY[%(param_1)s, %(param_2)s], "
+ "ARRAY[%(param_3)s, NULL]) -> %(hstore_1)s AS anon_1"),
+ False
+ )
+
+ def test_cols_hstore_single_array(self):
+ self._test_cols(
+ hstore(postgresql.array(['1', '2', '3', None]))['3'],
+ ("hstore(ARRAY[%(param_1)s, %(param_2)s, %(param_3)s, NULL]) "
+ "-> %(hstore_1)s AS anon_1"),
+ False
+ )
+
+ def test_cols_concat(self):
+ self._test_cols(
+ self.hashcol.concat(hstore(cast(self.test_table.c.id, Text), '3')),
+ ("test_table.hash || hstore(CAST(test_table.id AS TEXT), "
+ "%(param_1)s) AS anon_1"),
+ True
+ )
+
+ def test_cols_concat_op(self):
+ self._test_cols(
+ self.hashcol + self.hashcol,
+ "test_table.hash || test_table.hash AS anon_1",
+ True
+ )
+
+ def test_cols_concat_get(self):
+ self._test_cols(
+ (self.hashcol + self.hashcol)['foo'],
+ "test_table.hash || test_table.hash -> %(param_1)s AS anon_1"
+ )
+
+ def test_cols_keys(self):
+ self._test_cols(
+ self.hashcol.keys(),
+ "akeys(test_table.hash) AS akeys_1",
+ True
+ )
+
+ def test_cols_vals(self):
+ self._test_cols(
+ self.hashcol.vals(),
+ "avals(test_table.hash) AS avals_1",
+ True
+ )
+
+ def test_cols_array(self):
+ self._test_cols(
+ self.hashcol.array(),
+ "hstore_to_array(test_table.hash) AS hstore_to_array_1",
+ True
+ )
+
+ def test_cols_matrix(self):
+ self._test_cols(
+ self.hashcol.matrix(),
+ "hstore_to_matrix(test_table.hash) AS hstore_to_matrix_1",
+ True
+ )