Repository: kayak/pypika
Pull request #396 (2020-04-10 10:33:08)

Added "alias" supporting for criterions

coveralls: 
[![Coverage Status](https://coveralls.io/builds/29991458/badge)](https://coveralls.io/builds/29991458)

Coverage increased (+0.01%) to 97.765% when pulling **4b71540aa8fc155766e06236c37c7ef7f9d8ff43 on nibrag:criterions-with-alias** into **4d42bd93196e758faa004b334ee0501d6bb8b0e5 on kayak:master**.


Patch:
diff --git a/pypika/terms.py b/pypika/terms.py
index b524f9c..00a695e 100644
--- a/pypika/terms.py
+++ b/pypika/terms.py
@@ -730,11 +730,12 @@ class ContainsCriterion(Criterion):
         self.term = self.term.replace_table(current_table, new_table)
 
     def get_sql(self, subquery=None, **kwargs):
-        return "{term} {not_}IN {container}".format(
+        sql = "{term} {not_}IN {container}".format(
             term=self.term.get_sql(**kwargs),
             container=self.container.get_sql(subquery=True, **kwargs),
             not_="NOT " if self._is_negated else "",
         )
+        return format_alias_sql(sql, self.alias, **kwargs)
 
     @builder
     def negate(self):
@@ -774,11 +775,12 @@ class BetweenCriterion(Criterion):
 
     def get_sql(self, **kwargs):
         # FIXME escape
-        return "{term} BETWEEN {start} AND {end}".format(
+        sql = "{term} BETWEEN {start} AND {end}".format(
             term=self.term.get_sql(**kwargs),
             start=self.start.get_sql(**kwargs),
             end=self.end.get_sql(**kwargs),
         )
+        return format_alias_sql(sql, self.alias, **kwargs)
 
 
 class BitwiseAndCriterion(Criterion):
@@ -807,9 +809,10 @@ class BitwiseAndCriterion(Criterion):
         self.term = self.term.replace_table(current_table, new_table)
 
     def get_sql(self, **kwargs):
-        return "({term} & {value})".format(
+        sql = "({term} & {value})".format(
             term=self.term.get_sql(**kwargs), value=self.value,
         )
+        return format_alias_sql(sql, self.alias, **kwargs)
 
 
 class NullCriterion(Criterion):
@@ -835,8 +838,9 @@ class NullCriterion(Criterion):
         """
         self.term = self.term.replace_table(current_table, new_table)
 
-    def get_sql(self, **kwargs):
-        return "{term} IS NULL".format(term=self.term.get_sql(**kwargs),)
+    def get_sql(self, with_alias=False, **kwargs):
+        sql = "{term} IS NULL".format(term=self.term.get_sql(**kwargs),)
+        return format_alias_sql(sql, self.alias, **kwargs)
 
 
 class ComplexCriterion(BasicCriterion):


Test patch:
diff --git a/pypika/tests/test_criterions.py b/pypika/tests/test_criterions.py
index a882d2a..cb84f3b 100644
--- a/pypika/tests/test_criterions.py
+++ b/pypika/tests/test_criterions.py
@@ -90,6 +90,13 @@ class CriterionTests(unittest.TestCase):
         self.assertEqual('"foo" IS NULL', str(c1))
         self.assertEqual('"crit"."foo" IS NULL', str(c2))
 
+    def test__criterion_is_null_with_alias(self):
+        c1 = Field("foo").isnull().as_('alias')
+        c2 = Field("foo", table=self.t).isnull().as_('alias')
+
+        self.assertEqual('"foo" IS NULL "alias"', str(c1))
+        self.assertEqual('"crit"."foo" IS NULL "alias"', str(c2))
+
     def test__criterion_ne_number(self):
         c1 = Field("foo") != 1
         c2 = Field("foo", table=self.t).ne(0)
@@ -254,6 +261,11 @@ class CriterionTests(unittest.TestCase):
         self.assertEqual('("foo" & 2)', str(c1))
         self.assertEqual('("crit"."foo" & 10)=2', str(c2))
 
+    def test__criterion_bitwise_and_with_alias(self):
+        c1 = Field("foo").bitwiseand(2).as_('alias')
+
+        self.assertEqual('("foo" & 2) "alias"', str(c1))
+
 
 class NotTests(unittest.TestCase):
     table_abc, table_efg = Table("abc", alias="cx0"), Table("efg", alias="cx1")
@@ -322,6 +334,15 @@ class BetweenTests(unittest.TestCase):
         self.assertEqual('"btw"."foo" BETWEEN 0 AND 1', str(c2))
         self.assertEqual('"foo" BETWEEN 0 AND 1', str(c3))
 
+    def test__between_with_alias(self):
+        c1 = Field("foo").between(0, 1).as_('alias')
+        c2 = Field("foo", table=self.t).between(0, 1).as_('alias')
+        c3 = Field("foo")[0:1].as_('alias')
+
+        self.assertEqual('"foo" BETWEEN 0 AND 1 "alias"', str(c1))
+        self.assertEqual('"btw"."foo" BETWEEN 0 AND 1 "alias"', str(c2))
+        self.assertEqual('"foo" BETWEEN 0 AND 1 "alias"', str(c3))
+
     def test__between_date(self):
         c1 = Field("foo").between(date(2000, 1, 1), date(2000, 12, 31))
         c2 = Field("foo", table=self.t).between(date(2000, 1, 1), date(2000, 12, 31))
@@ -383,6 +404,13 @@ class IsInTests(unittest.TestCase):
         self.assertEqual('"foo" IN (0,1)', str(c1))
         self.assertEqual('"isin"."foo" IN (0,1)', str(c2))
 
+    def test__in_number_with_alias(self):
+        c1 = Field("foo").isin([0, 1]).as_('alias')
+        c2 = Field("foo", table=self.t).isin([0, 1]).as_('alias')
+
+        self.assertEqual('"foo" IN (0,1) "alias"', str(c1))
+        self.assertEqual('"isin"."foo" IN (0,1) "alias"', str(c2))
+
     def test__in_character(self):
         c1 = Field("foo").isin(["a", "b"])
         c2 = Field("foo", table=self.t).isin(["a", "b"])
@@ -437,6 +465,13 @@ class NotInTests(unittest.TestCase):
         self.assertEqual('"foo" NOT IN (0,1)', str(c1))
         self.assertEqual('"notin"."foo" NOT IN (0,1)', str(c2))
 
+    def test__notin_number_with_alias(self):
+        c1 = Field("foo").notin([0, 1]).as_('alias')
+        c2 = Field("foo", table=self.t).notin([0, 1]).as_('alias')
+
+        self.assertEqual('"foo" NOT IN (0,1) "alias"', str(c1))
+        self.assertEqual('"notin"."foo" NOT IN (0,1) "alias"', str(c2))
+
     def test__notin_character(self):
         c1 = Field("foo").notin(["a", "b"])
         c2 = Field("foo", table=self.t).notin(["a", "b"])