internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: ibis-project/ibis

Issue:
Display error message text with translation failure in interactive mode
Right now there is no transparency into where the failure occurred (as with `expr.execute()`)



Discussion:
this will now look like (on sqlite, say):

``` python
In [1]: db = ibis.sqlite.connect('ibis_testing.db')

In [2]: t = db.table('functional_alltypes')

In [3]: ibis.options.interactive = True

In [4]: t.double_col.sum()
Out[4]: 331785.00000000006

In [5]: t.double_col.app
t.double_col.approx_median   t.double_col.approx_nunique

In [5]: t.double_col.approx_nunique()
Out[5]: 
Translation to backend failed
Error message: No translator rule for <class 'ibis.expr.operations.HLLCardinality'>
Expression repr follows:
ref_0
SQLiteTable[table]
  name: functional_alltypes
  schema:
    index : int64
    Unnamed: 0 : int64
    id : int64
    bool_col : boolean
    tinyint_col : int64
    smallint_col : int64
    int_col : int64
    bigint_col : int64
    float_col : double
    double_col : double
    date_string_col : string
    string_col : int64
    timestamp_col : string
    year : int64
    month : int64

approx_nunique = HLLCardinality[double]
  double_col = Column[array(double)] 'double_col' from table ref_0
  None
```


Resolving patch:
diff --git a/ibis/expr/types.py b/ibis/expr/types.py
--- a/ibis/expr/types.py
+++ b/ibis/expr/types.py
@@ -49,9 +49,11 @@ def __repr__(self):
             try:
                 result = self.execute()
                 return repr(result)
-            except com.TranslationError:
-                output = ('Translation to backend failed, repr follows:\n%s'
-                          % self._repr())
+            except com.TranslationError as e:
+                output = ('Translation to backend failed\n'
+                          'Error message: {0}\n'
+                          'Expression repr follows:\n{1}'
+                          .format(e.args[0], self._repr()))
                 return output
         else:
             return self._repr()


Test patch:
diff --git a/ibis/sql/sqlite/tests/test_functions.py b/ibis/sql/sqlite/tests/test_functions.py
--- a/ibis/sql/sqlite/tests/test_functions.py
+++ b/ibis/sql/sqlite/tests/test_functions.py
@@ -261,6 +261,17 @@ def test_distinct_aggregates(self):
         ]
         self._execute_aggregation(table, exprs)
 
+    def test_interactive_repr_shows_error(self):
+        # #591. Doing this in SQLite because so many built-in functions are not
+        # available
+        import ibis.config as config
+
+        expr = self.alltypes.double_col.approx_nunique()
+
+        with config.option_context('interactive', True):
+            result = repr(expr)
+            assert 'no translator rule' in result.lower()
+
     def _execute_aggregation(self, table, exprs):
         agg_exprs = [expr.name('e%d' % i)
                      for i, expr in enumerate(exprs)]
Repository: ibis-project/ibis

Issue:
Convenience for specifying join keys that are shared in left and right tables
From the mailing list

``` python
joined = T1.join(T2, ['chrom', 'alt', 'pos'])
```



Discussion:

Resolving patch:
diff --git a/ibis/expr/operations.py b/ibis/expr/operations.py
--- a/ibis/expr/operations.py
+++ b/ibis/expr/operations.py
@@ -1303,6 +1303,8 @@ def output_type(self):
 
 class Join(TableNode):
 
+    _arg_names = ['left', 'right', 'predicates']
+
     def __init__(self, left, right, predicates):
         if not rules.is_table(left):
             raise TypeError('Can only join table expressions, got %s for '
@@ -1354,9 +1356,10 @@ def _clean_predicates(self, left, right, predicates):
                 lk = left._ensure_expr(lk)
                 rk = right._ensure_expr(rk)
                 pred = lk == rk
-            else:
-                # pred = L.substitute_parents(pred, past_projection=False)
-                pass
+            elif isinstance(pred, six.string_types):
+                pred = getattr(left, pred) == getattr(right, pred)
+            elif not isinstance(pred, ir.Expr):
+                raise NotImplementedError
 
             if not isinstance(pred, ir.BooleanArray):
                 raise com.ExpressionError('Join predicate must be comparison')


Test patch:
diff --git a/ibis/expr/tests/test_table.py b/ibis/expr/tests/test_table.py
--- a/ibis/expr/tests/test_table.py
+++ b/ibis/expr/tests/test_table.py
@@ -817,7 +817,21 @@ def test_filter_join_unmaterialized(self):
         repr(filtered)
 
     def test_join_overlapping_column_names(self):
-        pass
+        t1 = ibis.table([('foo', 'string'),
+                         ('bar', 'string'),
+                         ('value1', 'double')])
+        t2 = ibis.table([('foo', 'string'),
+                         ('bar', 'string'),
+                         ('value2', 'double')])
+
+        joined = t1.join(t2, 'foo')
+        expected = t1.join(t2, t1.foo == t2.foo)
+        assert_equal(joined, expected)
+
+        joined = t1.join(t2, ['foo', 'bar'])
+        expected = t1.join(t2, [t1.foo == t2.foo,
+                                t1.bar == t2.bar])
+        assert_equal(joined, expected)
 
     def test_join_key_alternatives(self):
         t1 = self.con.table('star1')
Repository: ibis-project/ibis

Issue:
Use async API to make Impala expression execution cancel on KeyboardInterrupt
Requested by user



Discussion:

Resolving patch:
diff --git a/ibis/impala/client.py b/ibis/impala/client.py
--- a/ibis/impala/client.py
+++ b/ibis/impala/client.py
@@ -16,6 +16,7 @@
 import re
 import six
 import threading
+import time
 import weakref
 
 import hdfs
@@ -54,6 +55,12 @@ def list_udas(self, like=None):
                                      database=self.name)
 
 
+def hs2_cursor_status(cursor):
+    from impala.hiveserver2 import get_operation_status
+    handle = cursor._last_operation_handle
+    return get_operation_status(cursor.service, handle)
+
+
 class ImpalaConnection(object):
 
     """
@@ -194,10 +201,42 @@ def release(self):
         self.con.connection_pool.put(self)
 
     def execute(self, stmt, async=False):
+        self.cursor.execute_async(stmt)
         if async:
-            self.cursor.execute_async(stmt)
+            return
         else:
-            self.cursor.execute(stmt)
+            self._wait_synchronous()
+
+    def _wait_synchronous(self):
+        # Wait to finish, but cancel if KeyboardInterrupt
+        from impala.hiveserver2 import OperationalError
+        loop_start = time.time()
+
+        def _sleep_interval(start_time):
+            elapsed = time.time() - start_time
+            if elapsed < 0.05:
+                return 0.01
+            elif elapsed < 1.0:
+                return 0.05
+            elif elapsed < 10.0:
+                return 0.1
+            elif elapsed < 60.0:
+                return 0.5
+            return 1.0
+
+        cur = self.cursor
+        try:
+            while True:
+                state = hs2_cursor_status(cur)
+                if self.cursor._op_state_is_error(state):
+                    raise OperationalError("Operation is in ERROR_STATE")
+                if not cur._op_state_is_executing(state):
+                    break
+                time.sleep(_sleep_interval(loop_start))
+        except KeyboardInterrupt:
+            print('Canceling query')
+            self.cancel()
+            raise
 
     def is_finished(self):
         return not self.is_executing()
@@ -285,10 +324,7 @@ def status(self):
         Retrieve Impala query status
         """
         self._wait_execute()
-        from impala.hiveserver2 import get_operation_status
-        cur = self._cursor
-        handle = cur._last_operation_handle
-        return get_operation_status(cur.service, handle)
+        return hs2_cursor_status(self._cursor)
 
     def wait(self, progress_bar=True):
         raise NotImplementedError


Test patch:
Repository: ibis-project/ibis

Issue:
ImpalaTable.describe_formatted may throw an exception
excerpt. Will investigate soon

``` python
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-115-87d40e40503e> in <module>()
----> 1 repr(db.csv_as_parquet.describe_formatted())

/home/wesm/code/cloudera/ibis/ibis/impala/metadata.py in __repr__(self)
    295             data['partition schema'] = self.partitions
    296 
--> 297         pprint.pprint(data, stream=buf)
    298 
    299         return buf.getvalue()

/home/wesm/anaconda3/lib/python3.5/pprint.py in pprint(object, stream, indent, width, depth, compact)
     51         stream=stream, indent=indent, width=width, depth=depth,
     52         compact=compact)
---> 53     printer.pprint(object)
     54 
     55 def pformat(object, indent=1, width=80, depth=None, *, compact=False):
```



Discussion:

Resolving patch:
diff --git a/ibis/impala/metadata.py b/ibis/impala/metadata.py
--- a/ibis/impala/metadata.py
+++ b/ibis/impala/metadata.py
@@ -43,14 +43,16 @@ def _converter(tup):
 
 def _try_timestamp(x):
     try:
-        return pd.Timestamp(x)
+        ts = pd.Timestamp(x)
+        return ts.to_pydatetime()
     except (ValueError, TypeError):
         return x
 
 
 def _try_unix_timestamp(x):
     try:
-        return pd.Timestamp.fromtimestamp(int(x))
+        ts = pd.Timestamp.fromtimestamp(int(x))
+        return ts.to_pydatetime()
     except (ValueError, TypeError):
         return x
 


Test patch:
Repository: ibis-project/ibis

Issue:
Add a groupby alias for TableExpr.group_by



Discussion:

Resolving patch:
diff --git a/ibis/expr/types.py b/ibis/expr/types.py
--- a/ibis/expr/types.py
+++ b/ibis/expr/types.py
@@ -702,6 +702,11 @@ def group_by(self, by=None, **additional_grouping_expressions):
         --------
         x.group_by([b1, b2]).aggregate(metrics)
 
+        Notes
+        -----
+        group_by and groupby are equivalent, with `groupby` being provided for
+        ease-of-use for pandas users.
+
         Returns
         -------
         grouped_expr : GroupedTableExpr
@@ -709,6 +714,8 @@ def group_by(self, by=None, **additional_grouping_expressions):
         from ibis.expr.groupby import GroupedTableExpr
         return GroupedTableExpr(self, by, **additional_grouping_expressions)
 
+    groupby = group_by
+
 
 # -----------------------------------------------------------------------------
 # Declare all typed ValueExprs. This is what the user will actually interact


Test patch:
diff --git a/ibis/expr/tests/test_table.py b/ibis/expr/tests/test_table.py
--- a/ibis/expr/tests/test_table.py
+++ b/ibis/expr/tests/test_table.py
@@ -485,6 +485,13 @@ def test_aggregate_keywords(self):
         assert_equal(expr, expected)
         assert_equal(expr2, expected)
 
+    def test_groupby_alias(self):
+        t = self.table
+
+        result = t.groupby('g').size()
+        expected = t.group_by('g').size()
+        assert_equal(result, expected)
+
     def test_summary_expand_list(self):
         summ = self.table.f.summary()
Repository: ibis-project/ibis

Issue:
Display argument names in default Expr repr



Discussion:

Resolving patch:
diff --git a/ibis/expr/format.py b/ibis/expr/format.py
--- a/ibis/expr/format.py
+++ b/ibis/expr/format.py
@@ -188,10 +188,10 @@ def _format_column(self, expr):
             self.memo.observe(parent, formatter=self._format_node)
 
         table_formatted = self.memo.get_alias(parent)
-        table_formatted = '\n' + self._indent(table_formatted)
+        table_formatted = self._indent(table_formatted)
 
         type_display = self._get_type_display(self.expr)
-        return ("Column[{0}] '{1}' from table {2}"
+        return ("Column[{0}] '{1}' from table\n{2}"
                 .format(type_display, col.name, table_formatted))
 
     def _format_node(self, expr):
@@ -209,9 +209,9 @@ def visit(what, extra_indents=0):
 
             formatted_args.append(result)
 
-        arg_names = getattr(op, '_arg_names', None)
+        arg_names = op._arg_names
 
-        if arg_names is None:
+        if not arg_names:
             for arg in op.args:
                 if isinstance(arg, list):
                     for x in arg:
@@ -241,7 +241,6 @@ def visit(what, extra_indents=0):
         opname = type(op).__name__
         type_display = self._get_type_display(expr)
         opline = '%s[%s]' % (opname, type_display)
-
         return '\n'.join([opline] + formatted_args)
 
     def _format_subexpr(self, expr):
diff --git a/ibis/expr/types.py b/ibis/expr/types.py
--- a/ibis/expr/types.py
+++ b/ibis/expr/types.py
@@ -322,6 +322,15 @@ def output_type(self):
         """
         raise NotImplementedError
 
+    @property
+    def _arg_names(self):
+        try:
+            input_type = self.__class__.input_type
+        except AttributeError:
+            return []
+        else:
+            return [t.name for t in input_type.types]
+
 
 def all_equal(left, right, cache=None):
     if isinstance(left, list):
@@ -349,7 +358,7 @@ def arg_accessor(self):
 class ValueOp(Node):
 
     def __init__(self, *args):
-        Node.__init__(self, args)
+        super(ValueOp, self).__init__(args)
 
     def root_tables(self):
         exprs = [arg for arg in self.args if isinstance(arg, Expr)]


Test patch:
diff --git a/ibis/expr/tests/test_format.py b/ibis/expr/tests/test_format.py
--- a/ibis/expr/tests/test_format.py
+++ b/ibis/expr/tests/test_format.py
@@ -217,3 +217,23 @@ def test_memoize_filtered_tables_in_join(self):
 
         # Join, and one for each aggregation
         assert result.count('predicates') == 3
+
+
+def test_argument_repr_shows_name():
+    t = ibis.table([('a', 'int64')])
+    expr = t.a.nullif(2)
+    result = repr(expr)
+    expected = """\
+ref_0
+UnboundTable[table]
+  name: None
+  schema:
+    a : int64
+
+NullIf[array(int64)]
+  a = Column[array(int64)] 'a' from table
+    ref_0
+  null_if_expr:
+    Literal[int8]
+      2"""
+    assert result == expected
Repository: ibis-project/ibis

Issue:
Enum rule does not conform argument to an enum value
Enum values pass through unmodified, e.g.

```
class MyEnum(enum.Enum):
    FOO = 'foo'
    BAR = 'bar'
```

the validator passes through `'foo'` rather than returning `MyEnum.FOO`


Discussion:
ah, right. on it.

Resolving patch:
diff --git a/ibis/expr/rules.py b/ibis/expr/rules.py
--- a/ibis/expr/rules.py
+++ b/ibis/expr/rules.py
@@ -670,9 +670,9 @@ def _validate(self, args, i):
 
         # if our passed value wasn't specified directly from the enum
         if not isinstance(arg, self.enum):
-            value_set = Counter(
-                key.value for key in self.enum.__members__.values()
-            )
+            value_set = {}
+            for key, value in self.enum.__members__.items():
+                value_set.setdefault(value.value, []).append(key)
 
             # not in the value_set, so can't be valid
             if arg not in value_set:
@@ -686,13 +686,14 @@ def _validate(self, args, i):
             # if it's in the value set and the value set has duplicates, then
             # we can't validate it because we don't know which one the user
             # meant
-            if value_set[arg] > 1:
+            if len(value_set[arg]) > 1:
                 raise IbisTypeError(
                     (
                         'Value {0} is a member of {1}, but {1} is not unique. '
                         'Please explicitly pass the desired enum attribute.'
                     ).format(arg, self.enum.__name__)
                 )
+            return self.enum[value_set[arg].pop()]
         return arg
 
 


Test patch:
diff --git a/ibis/expr/tests/test_rules.py b/ibis/expr/tests/test_rules.py
--- a/ibis/expr/tests/test_rules.py
+++ b/ibis/expr/tests/test_rules.py
@@ -43,6 +43,9 @@ def output_type(self):
     op = MyOp(Foo.a)
     assert op._validate_args(op.args) == [Foo.a]
 
+    op = MyOp(2)
+    assert op._validate_args(op.args) == [Foo.b]
+
 
 def test_duplicate_enum():
     enum = pytest.importorskip('enum')
Repository: ibis-project/ibis

Issue:
literal([1, 2, 'a']) doesn't fail



Discussion:

Resolving patch:
diff --git a/ibis/expr/types.py b/ibis/expr/types.py
--- a/ibis/expr/types.py
+++ b/ibis/expr/types.py
@@ -498,7 +498,9 @@ def output_type(self):
         elif isinstance(value, datetime.date):
             return DateScalar
         elif isinstance(value, list):
-            value_type = rules.highest_precedence_type(map(literal, value))
+            value_type = rules.highest_precedence_type(
+                list(map(literal, value))
+            )
             return lambda value, value_type=value_type: ArrayScalar(
                 value, dt.Array(value_type)
             )


Test patch:
diff --git a/ibis/expr/tests/test_datatypes.py b/ibis/expr/tests/test_datatypes.py
--- a/ibis/expr/tests/test_datatypes.py
+++ b/ibis/expr/tests/test_datatypes.py
@@ -213,3 +213,9 @@ class MyOperation(types.Node):
 
     with pytest.raises(IbisError):
         MyOperation([api.literal('string')])
+
+
+def test_literal_mixed_type_fails():
+    data = [1, 'a']
+    with pytest.raises(TypeError):
+        ibis.literal(data)
Repository: ibis-project/ibis

Issue:
[MapD] Missing entry for `float32` in `_sql_type_names` at operations.py
In `_sql_type_names` at https://github.com/ibis-project/ibis/blob/master/ibis/mapd/operations.py#L18 , it is missing a entry for `'float32': 'float'`


Discussion:

Resolving patch:
diff --git a/ibis/mapd/ddl.py b/ibis/mapd/ddl.py
--- a/ibis/mapd/ddl.py
+++ b/ibis/mapd/ddl.py
@@ -404,8 +404,3 @@ def pieces(self):
 
     def compile(self):
         return '\n'.join(self.pieces)
-
-
-def _mapd_input_signature(inputs):
-    # TODO: varargs '{}...'.format(val)
-    return ', '.join(map(_type_to_sql_string, inputs))
diff --git a/ibis/mapd/operations.py b/ibis/mapd/operations.py
--- a/ibis/mapd/operations.py
+++ b/ibis/mapd/operations.py
@@ -16,19 +16,23 @@
 import ibis.expr.operations as ops
 
 _sql_type_names = {
+    'boolean': 'boolean',
+    'date': 'date',
+    'decimal': 'decimal',
+    'double': 'double',
+    'float32': 'float',
+    'float64': 'double',
     'int8': 'smallint',
     'int16': 'smallint',
     'int32': 'int',
     'int64': 'bigint',
-    'float': 'float',
-    'float64': 'double',
-    'double': 'double',
+    'linestring': 'linestring',
+    'multipolygon': 'multipolygon',
+    'point': 'point',
+    'polygon': 'polygon',
     'string': 'text',
-    'boolean': 'boolean',
-    'timestamp': 'timestamp',
-    'decimal': 'decimal',
-    'date': 'date',
     'time': 'time',
+    'timestamp': 'timestamp',
 }
 
 


Test patch:
diff --git a/ibis/mapd/tests/test_client.py b/ibis/mapd/tests/test_client.py
--- a/ibis/mapd/tests/test_client.py
+++ b/ibis/mapd/tests/test_client.py
@@ -84,3 +84,36 @@ def test_union_op(alltypes):
     expr = t1.union(t2)
     with pytest.raises(com.UnsupportedOperationError):
         expr.compile()
+
+
+def test_create_table_schema(con):
+    t_name = 'mytable'
+
+    con.drop_table(t_name, force=True)
+
+    schema = ibis.schema([
+        ('a', 'float'),
+        ('b', 'double'),
+        ('c', 'int32'),
+        ('d', 'int64'),
+        ('x', 'point'),
+        ('y', 'linestring'),
+        ('z', 'polygon'),
+        ('w', 'multipolygon')
+    ])
+
+    con.create_table(t_name, schema=schema)
+
+    try:
+        t = con.table(t_name)
+
+        assert isinstance(t.a, ir.FloatingColumn)
+        assert isinstance(t.b, ir.FloatingColumn)
+        assert isinstance(t.c, ir.IntegerColumn)
+        assert isinstance(t.d, ir.IntegerColumn)
+        assert isinstance(t.x, ir.PointColumn)
+        assert isinstance(t.y, ir.LineStringColumn)
+        assert isinstance(t.z, ir.PolygonColumn)
+        assert isinstance(t.w, ir.MultiPolygonColumn)
+    finally:
+        con.drop_table(t_name)
Repository: ibis-project/ibis

Issue:
MapD  str.to_timestamp() : No translation rule for <class 'ibis.expr.operations.StringToTimestamp'>
expr = ibis.literal('20170206').to_timestamp('%Y%m%d')
client.execute(expr)

ibis.common.OperationNotDefinedError: No translation rule for <class 'ibis.expr.operations.StringToTimestamp'>

Backend=MapD_4.1.1    ibis=0.14    Python=3.6  Ubuntu=18.04    Anaconda=5.1


Discussion:
thanks @lzhmhznr for point us that

I am checking the issues related to MapD and we are planing to add new features to ibis-mapd also.

@cpcloud could you add a "MapD" flag to this issue? 
@lzhmhznr at this moment this operation is not supported by mapd database. I will change to this function to raise Unsupported Exception.

Resolving patch:
diff --git a/ibis/mapd/operations.py b/ibis/mapd/operations.py
--- a/ibis/mapd/operations.py
+++ b/ibis/mapd/operations.py
@@ -783,6 +783,7 @@ class ByteLength(ops.StringLength):
     ops.StringReplace,
     ops.StringJoin,
     ops.StringSplit,
+    ops.StringToTimestamp,
     ops.Translate,
     ops.StringAscii,
     ops.LPad,


Test patch:
Repository: ibis-project/ibis

Issue:
NullIf should enforce that its arguments are castable to a common type



Discussion:

Resolving patch:
diff --git a/ibis/expr/operations.py b/ibis/expr/operations.py
--- a/ibis/expr/operations.py
+++ b/ibis/expr/operations.py
@@ -395,7 +395,7 @@ class NullIf(ValueOp):
 
     arg = Arg(rlz.any)
     null_if_expr = Arg(rlz.any)
-    output_type = rlz.typeof('arg')
+    output_type = rlz.shape_like('args')
 
 
 class NullIfZero(ValueOp):


Test patch:
diff --git a/ibis/expr/tests/test_value_exprs.py b/ibis/expr/tests/test_value_exprs.py
--- a/ibis/expr/tests/test_value_exprs.py
+++ b/ibis/expr/tests/test_value_exprs.py
@@ -1460,3 +1460,33 @@ def test_window_unbounded_invalid(kind, begin, end):
     kwargs = {kind: (begin, end)}
     with pytest.raises(com.IbisInputError):
         ibis.window(**kwargs)
+
+
+@pytest.mark.parametrize(
+    ('left', 'right', 'expected'),
+    [
+        (ibis.literal(1), ibis.literal(1.0), dt.float64),
+        (ibis.literal('a'), ibis.literal('b'), dt.string),
+        (ibis.literal(1.0), ibis.literal(1), dt.float64),
+        (ibis.literal(1), ibis.literal(1), dt.int8),
+        (ibis.literal(1), ibis.literal(1000), dt.int16),
+        (ibis.literal(2 ** 16), ibis.literal(2 ** 17), dt.int32),
+        (ibis.literal(2 ** 50), ibis.literal(1000), dt.int64),
+        (ibis.literal([1, 2]), ibis.literal([1, 2]), dt.Array(dt.int8)),
+        (ibis.literal(['a']), ibis.literal([]), dt.Array(dt.string)),
+        (ibis.literal([]), ibis.literal(['a']), dt.Array(dt.string)),
+        (ibis.literal([]), ibis.literal([]), dt.Array(dt.null)),
+    ],
+)
+def test_nullif_type(left, right, expected):
+    assert left.nullif(right).type() == expected
+
+
+@pytest.mark.parametrize(
+    ('left', 'right'), [(ibis.literal(1), ibis.literal('a'))]
+)
+def test_nullif_fail(left, right):
+    with pytest.raises(com.IbisTypeError):
+        left.nullif(right)
+    with pytest.raises(com.IbisTypeError):
+        right.nullif(left)
diff --git a/ibis/impala/tests/test_exprs.py b/ibis/impala/tests/test_exprs.py
--- a/ibis/impala/tests/test_exprs.py
+++ b/ibis/impala/tests/test_exprs.py
@@ -520,7 +520,15 @@ def test_nullif_ifnull(self):
         f = table.l_quantity
 
         cases = [
-            (f.nullif(f == 0), 'nullif(`l_quantity`, `l_quantity` = 0)'),
+            (f.nullif(f), 'nullif(`l_quantity`, `l_quantity`)'),
+            (
+                (f == 0).nullif(f == 0),
+                'nullif(`l_quantity` = 0, `l_quantity` = 0)',
+            ),
+            (
+                (f != 0).nullif(f == 0),
+                'nullif(`l_quantity` != 0, `l_quantity` = 0)',
+            ),
             (f.fillna(0), 'isnull(`l_quantity`, CAST(0 AS decimal(12, 2)))'),
         ]
         self._check_expr_cases(cases)