Repository: kayak/pypika
Pull request #24 (2016-12-05 11:19:38)

Fixed criterion aliases to properly serialize to sql


Patch:
diff --git a/pypika/terms.py b/pypika/terms.py
index eba423a..9692fd7 100644
--- a/pypika/terms.py
+++ b/pypika/terms.py
@@ -279,12 +279,9 @@ class Criterion(Term):
     def __str__(self):
         return self.get_sql()
 
-    def get_sql(self):
-        raise NotImplementedError()
-
 
 class BasicCriterion(Criterion):
-    def __init__(self, comparator, left, right):
+    def __init__(self, comparator, left, right, alias=None):
         """
         A wrapper for a basic criterion such as equality or inequality.  This wraps three parts, a left and right term
         and a comparator which defines the type of comparison.
@@ -298,6 +295,7 @@ class BasicCriterion(Criterion):
         :param right:
             The term on the right side of the expression.
         """
+        super(BasicCriterion, self).__init__(alias)
         self.comparator = comparator
         self.left = left
         self.right = right
@@ -315,16 +313,20 @@ class BasicCriterion(Criterion):
     def fields(self):
         return self.left.fields() + self.right.fields()
 
-    def get_sql(self, **kwargs):
-        return '{left}{comparator}{right}'.format(
+    def get_sql(self, with_alias=False, **kwargs):
+        sql = '{left}{comparator}{right}'.format(
             comparator=self.comparator.value,
             left=self.left.get_sql(**kwargs),
             right=self.right.get_sql(**kwargs),
         )
+        if with_alias and self.alias:
+            return '{sql} "{alias}"'.format(sql=sql, alias=self.alias)
+
+        return sql
 
 
 class ContainsCriterion(Criterion):
-    def __init__(self, term, container):
+    def __init__(self, term, container, alias=None):
         """
         A wrapper for a "IN" criterion.  This wraps two parts, a term and a container.  The term is the part of the
         expression that is checked for membership in the container.  The container can either be a list or a subquery.
@@ -335,6 +337,7 @@ class ContainsCriterion(Criterion):
         :param container:
             A list or subquery.
         """
+        super(ContainsCriterion, self).__init__(alias)
         self.term = term
         self.container = container
 
@@ -350,7 +353,8 @@ class ContainsCriterion(Criterion):
 
 
 class BetweenCriterion(Criterion):
-    def __init__(self, term, start, end):
+    def __init__(self, term, start, end, alias=None):
+        super(BetweenCriterion, self).__init__(alias)
         self.term = term
         self.start = start
         self.end = end
@@ -377,7 +381,8 @@ class BetweenCriterion(Criterion):
 
 
 class NullCriterion(Criterion):
-    def __init__(self, term, isnull):
+    def __init__(self, term, isnull, alias=None):
+        super(NullCriterion, self).__init__(alias)
         self.term = term
         self.isnull = isnull
 


Test patch:
diff --git a/pypika/tests/test_criterions.py b/pypika/tests/test_criterions.py
index 12001de..827a502 100644
--- a/pypika/tests/test_criterions.py
+++ b/pypika/tests/test_criterions.py
@@ -10,12 +10,13 @@ __email__ = "theys@kayak.com"
 
 
 class CriterionTests(unittest.TestCase):
-    t = Table('test', alias = 'crit')
+    t = Table('test', alias='crit')
 
     def test__criterion_with_alias(self):
         c1 = (Field('foo') == Field('bar')).as_('criterion')
 
         self.assertEqual('"foo"="bar"', str(c1))
+        self.assertEqual('"foo"="bar" "criterion"', c1.get_sql(with_alias=True))
 
     def test__criterion_eq_number(self):
         c1 = Field('foo') == 1
@@ -245,7 +246,7 @@ class CriterionTests(unittest.TestCase):
 
 
 class BetweenTests(unittest.TestCase):
-    t = Table('abc', alias = 'btw')
+    t = Table('abc', alias='btw')
 
     def test__between_number(self):
         c1 = Field('foo').between(0, 1)
@@ -294,7 +295,7 @@ class BetweenTests(unittest.TestCase):
 
 
 class IsInTests(unittest.TestCase):
-    t = Table('abc',alias = 'isin')
+    t = Table('abc', alias='isin')
 
     def test__in_number(self):
         c1 = Field('foo').isin([0, 1])