Repository: iterative/datachain

Issue:
`limit()` ignored after `show()`
In some cases, `.limit()` seems to have no effect. Here's a reproducer:
```python
from datachain import DataChain

img_dc = DataChain.from_storage("gs://datachain-demo/newyorker_caption_contest/images")
img_dc.show(3)
assert img_dc.limit(10).count() == 10
```
Commenting out `img_dc.show(3)` makes the assert succeed as expected.

Note that I've only been able to reproduce the failure with a real bucket, but not in tests.


Discussion:
cloudflare-pages[bot]: ## Deploying datachain-documentation with &nbsp;<a href="https://pages.dev"><img alt="Cloudflare Pages" src="https://user-images.githubusercontent.com/23264/106598434-9e719e00-654f-11eb-9e59-6167043cfa01.png" width="16"></a> &nbsp;Cloudflare Pages

<table><tr><td><strong>Latest commit:</strong> </td><td>
<code>f3bf112</code>
</td></tr>
<tr><td><strong>Status:</strong></td><td>&nbsp;✅&nbsp; Deploy successful!</td></tr>
<tr><td><strong>Preview URL:</strong></td><td>
<a href='https://33809ae1.datachain-documentation.pages.dev'>https://33809ae1.datachain-documentation.pages.dev</a>
</td></tr>
<tr><td><strong>Branch Preview URL:</strong></td><td>
<a href='https://fix-show-limit.datachain-documentation.pages.dev'>https://fix-show-limit.datachain-documentation.pages.dev</a>
</td></tr>
</table>

[View logs](https://dash.cloudflare.com/?to=/:account/pages/view/datachain-documentation/33809ae1-69af-4f51-83bd-000dfb4d245f)


Patch:
diff --git a/src/datachain/lib/dc.py b/src/datachain/lib/dc.py
index cae56b5..a91e2fa 100644
--- a/src/datachain/lib/dc.py
+++ b/src/datachain/lib/dc.py
@@ -193,8 +193,6 @@ class DataChain(DatasetQuery):
         ```
     """
 
-    max_row_count: Optional[int] = None
-
     DEFAULT_FILE_RECORD: ClassVar[dict] = {
         "source": "",
         "name": "",
@@ -1603,18 +1601,7 @@ class DataChain(DatasetQuery):
     @detach
     def limit(self, n: int) -> "Self":
         """Return the first n rows of the chain."""
-        n = max(n, 0)
-
-        if self.max_row_count is None:
-            self.max_row_count = n
-            return super().limit(n)
-
-        limit = min(n, self.max_row_count)
-        if limit == self.max_row_count:
-            return self
-
-        self.max_row_count = limit
-        return super().limit(self.max_row_count)
+        return super().limit(n)
 
     @detach
     def offset(self, offset: int) -> "Self":
diff --git a/src/datachain/query/dataset.py b/src/datachain/query/dataset.py
index 9a05044..5407119 100644
--- a/src/datachain/query/dataset.py
+++ b/src/datachain/query/dataset.py
@@ -1383,6 +1383,9 @@ class DatasetQuery:
     @detach
     def limit(self, n: int) -> "Self":
         query = self.clone(new_table=False)
+        for step in query.steps:
+            if isinstance(step, SQLLimit) and step.n < n:
+                return query
         query.steps.append(SQLLimit(n))
         return query
 


Test patch:
diff --git a/tests/unit/lib/test_datachain.py b/tests/unit/lib/test_datachain.py
index d7cc1de..2db6f1f 100644
--- a/tests/unit/lib/test_datachain.py
+++ b/tests/unit/lib/test_datachain.py
@@ -1228,3 +1228,33 @@ def test_custom_model_with_nested_lists():
             traces_double=[[{"x": 0.5, "y": 0.5}], [{"x": 0.5, "y": 0.5}]],
         )
     ]
+
+
+def test_min_limit():
+    dc = DataChain.from_values(a=[1, 2, 3, 4, 5])
+    assert dc.count() == 5
+    assert dc.limit(4).count() == 4
+    assert dc.count() == 5
+    assert dc.limit(1).count() == 1
+    assert dc.count() == 5
+    assert dc.limit(2).limit(3).count() == 2
+    assert dc.count() == 5
+    assert dc.limit(3).limit(2).count() == 2
+    assert dc.count() == 5
+
+
+def test_show_limit():
+    dc = DataChain.from_values(a=[1, 2, 3, 4, 5])
+    assert dc.count() == 5
+    assert dc.limit(4).count() == 4
+    dc.show(1)
+    assert dc.count() == 5
+    assert dc.limit(1).count() == 1
+    dc.show(1)
+    assert dc.count() == 5
+    assert dc.limit(2).limit(3).count() == 2
+    dc.show(1)
+    assert dc.count() == 5
+    assert dc.limit(3).limit(2).count() == 2
+    dc.show(1)
+    assert dc.count() == 5