# Buggy code
def _collect_info(self, engine_or_conn, selectable, columns, test_rows):
    from sqlalchemy import sql

    # fetch test DataFrame
    if columns:
        query = sql.select([sql.column(c) for c in columns], from_obj=selectable).limit(
            test_rows
        )
    else:
        query = sql.select("*", from_obj=selectable).limit(test_rows)
    test_df = pd.read_sql(
        query,
        engine_or_conn,
        index_col=self._index_col,
        coerce_float=self._coerce_float,
        parse_dates=self._parse_dates,
    )
    self._row_memory_usage = (
        test_df.memory_usage(deep=True, index=True).sum() / test_rows
    )

    if self._method == "offset":
        # fetch size
        size = list(
            engine_or_conn.execute(
                sql.select([sql.func.count()]).select_from(selectable)
            )
        )[0][0]
        shape = (size, test_df.shape[1])
    else:
        shape = (np.nan, test_df.shape[1])

    return test_df, shape


# Traceback (OverflowError)
In [1]: import mars.dataframe as md

In [7]: import sqlalchemy as sa

In [9]: con = sa.create_engine('sqlite:///database.sqlite', echo=False)

In [10]: df = md.read_sql('loan', con)

In [11]: df.head().execute()
Out[11]:
id member_id loan_amnt funded_amnt funded_amnt_inv        term int_rate installment grade sub_grade  ... hardship_payoff_balance_amount hardship_last_payment_amount disbursement_method debt_settlement_flag debt_settlement_flag_date settlement_status settlement_date settlement_amount settlement_percentage settlement_term
0                   1000        1000               0   36 months    10.71       32.61     B        B5  ...                                                                            Cash                    N
1                   1000        1000               0   36 months    16.08        35.2     F        F2  ...                                                                            Cash                    N
2                   1000        1000               0   36 months     9.45       32.01     B        B1  ...                                                                            Cash                    N
3                   1000        1000               0   36 months     9.64       32.11     B        B4  ...                                                                            Cash                    N
4                   1000        1000  0.004353680261   36 months    11.28       32.88     C        C1  ...                                                                            Cash                    N

[5 rows x 145 columns]

In [12]: df = md.read_sql("select * from loan where grade='A' and disbursement_method='cash'", con)

In [13]: df.head().execute()
/Users/xuyeqin/Workspace/mars/mars/dataframe/datasource/read_sql.py:277: RuntimeWarning: divide by zero encountered in double_scalars
chunk_size = (int(options.chunk_store_limit / op.row_memory_usage), df.shape[1])
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-13-017f342e9a9d> in <module>
----> 1 df.head().execute()

~/Workspace/mars/mars/core.py in execute(self, session, **kw)
560
561     def execute(self, session=None, **kw):
--> 562         self._data.execute(session, **kw)
563         return self
564

~/Workspace/mars/mars/core.py in execute(self, session, **kw)
369
370         # no more fetch, thus just fire run
--> 371         session.run(self, **kw)
372         # return Tileable or ExecutableTuple itself
373         return self

~/Workspace/mars/mars/session.py in run(self, *tileables, **kw)
426         tileables = tuple(mt.tensor(t) if not isinstance(t, (Entity, Base)) else t
427                           for t in tileables)
--> 428         result = self._sess.run(*tileables, **kw)
429
430         for t in tileables:

~/Workspace/mars/mars/session.py in run(self, *tileables, **kw)
103             # set number of running cores
104             self.context.set_ncores(kw['n_parallel'])
--> 105             res = self._executor.execute_tileables(tileables, **kw)
106             return res
107

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
387                 _kernel_mode.eager = False
388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
390         finally:
391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/utils.py in inner(*args, **kwargs)
481     def inner(*args, **kwargs):
482         with build_mode():
--> 483             return func(*args, **kwargs)
484     return inner
485

~/Workspace/mars/mars/executor.py in execute_tileables(self, tileables, fetch, n_parallel, n_thread, print_progress, mock, compose, name)
840                 # build chunk graph, tile will be done during building
841                 chunk_graph = chunk_graph_builder.build(
--> 842                     tileables, tileable_graph=tileable_graph)
843                 tileable_graph = chunk_graph_builder.prev_tileable_graph
844                 temp_result_keys = set(result_keys)

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
387                 _kernel_mode.eager = False
388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
390         finally:
391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/utils.py in inner(*args, **kwargs)
481     def inner(*args, **kwargs):
482         with build_mode():
--> 483             return func(*args, **kwargs)
484     return inner
485

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
348
349         chunk_graph = super().build(
--> 350             tileables, tileable_graph=tileable_graph)
351         self._iterative_chunk_graphs.append(chunk_graph)
352         if len(self._interrupted_ops) == 0:

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
387                 _kernel_mode.eager = False
388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
390         finally:
391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/utils.py in inner(*args, **kwargs)
481     def inner(*args, **kwargs):
482         with build_mode():
--> 483             return func(*args, **kwargs)
484     return inner
485

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
261                     # for further execution
262                     partial_tiled_chunks = \
--> 263                         self._on_tile_failure(tileable_data.op, exc_info)
264                     if partial_tiled_chunks is not None and \
265                             len(partial_tiled_chunks) > 0:

~/Workspace/mars/mars/tiles.py in inner(op, exc_info)
300                     on_tile_failure(op, exc_info)
301                 else:
--> 302                     raise exc_info[1].with_traceback(exc_info[2]) from None
303         return inner
304

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
241                 continue
242             try:
--> 243                 tiled = self._tile(tileable_data, tileable_graph)
244                 tiled_op.add(tileable_data.op)
245                 for t, td in zip(tileable_data.op.outputs, tiled):

~/Workspace/mars/mars/tiles.py in _tile(self, tileable_data, tileable_graph)
336         if any(inp.op in self._interrupted_ops for inp in tileable_data.inputs):
337             raise TilesError('Tile fail due to failure of inputs')
--> 338         return super()._tile(tileable_data, tileable_graph)
339
340     @kernel_mode

~/Workspace/mars/mars/tiles.py in _tile(self, tileable_data, tileable_graph)
199                 t._nsplits = o.nsplits
200         elif on_tile is None:
--> 201             tds[0]._inplace_tile()
202         else:
203             tds = on_tile(tileable_data.op.outputs, tds)

~/Workspace/mars/mars/core.py in _inplace_tile(self)
161
162     def _inplace_tile(self):
--> 163         return handler.inplace_tile(self)
164
165     def __getattr__(self, attr):

~/Workspace/mars/mars/tiles.py in inplace_tile(self, to_tile)
134         if not to_tile.is_coarse():
135             return to_tile
--> 136         dispatched = self.dispatch(to_tile.op)
137         self._assign_to([d.data for d in dispatched], to_tile.op.outputs)
138         return to_tile

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
387                 _kernel_mode.eager = False
388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
390         finally:
391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/tiles.py in dispatch(self, op)
117         else:
118             try:
--> 119                 tiled = op_cls.tile(op)
120             except NotImplementedError as ex:
121                 cause = ex

~/Workspace/mars/mars/dataframe/datasource/read_sql.py in tile(cls, op)
370     def tile(cls, op: 'DataFrameReadSQL'):
371         if op.method == 'offset':
--> 372             return cls._tile_offset(op)
373         else:
374             return cls._tile_partition(op)

~/Workspace/mars/mars/dataframe/datasource/read_sql.py in _tile_offset(cls, op)
275         chunk_size = df.extra_params.raw_chunk_size or options.chunk_size
276         if chunk_size is None:
--> 277             chunk_size = (int(options.chunk_store_limit / op.row_memory_usage), df.shape[1])
278         row_chunk_sizes = normalize_chunk_sizes(df.shape, chunk_size)[0]
279         offsets = np.cumsum((0,) + row_chunk_sizes)

OverflowError: cannot convert float infinity to integer

# Fixed code
def _collect_info(self, engine_or_conn, selectable, columns, test_rows):
    from sqlalchemy import sql

    # fetch test DataFrame
    if columns:
        query = sql.select([sql.column(c) for c in columns], from_obj=selectable).limit(
            test_rows
        )
    else:
        query = sql.select("*", from_obj=selectable).limit(test_rows)
    test_df = pd.read_sql(
        query,
        engine_or_conn,
        index_col=self._index_col,
        coerce_float=self._coerce_float,
        parse_dates=self._parse_dates,
    )
    if len(test_df) == 0:
        self._row_memory_usage = None
    else:
        self._row_memory_usage = test_df.memory_usage(
            deep=True, index=True
        ).sum() / len(test_df)

    if self._method == "offset":
        # fetch size
        size = list(
            engine_or_conn.execute(
                sql.select([sql.func.count()]).select_from(selectable)
            )
        )[0][0]
        shape = (size, test_df.shape[1])
    else:
        shape = (np.nan, test_df.shape[1])

    return test_df, shape