We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
🪲stats for distinct incorrect
### Thank you for taking the time to report a problem with Opteryx.
_To help us to respond to your request we ask that you try to provide the below detail about the bug._

**Describe the bug** _A clear and specific description of what the bug is. What the error, incorrect or unexpected behaviour was._


**Expected behaviour** _A clear and concise description of what you expected to happen._


**Sample Code/Statement** _If you can, please submit the SQL statement or Python code snippet, or a representative example using the sample datasets._

~~~sql

~~~

**Additional context** _Add any other context about the problem here, for example what you have done to try to diagnose or workaround the problem._


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opteryx/operators/distinct_node.py`
Content:
```
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 #     http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
12 
13 """
14 Distinct Node
15 
16 This is a SQL Query Execution Plan Node.
17 
18 This Node eliminates duplicate records.
19 """
20 import time
21 from typing import Generator
22 
23 import pyarrow
24 import pyarrow.compute
25 
26 from opteryx.models import QueryProperties
27 from opteryx.operators import BasePlanNode
28 
29 
30 class DistinctNode(BasePlanNode):
31     def __init__(self, properties: QueryProperties, **config):
32         super().__init__(properties=properties)
33         self._distinct_on = config.get("on")
34         if self._distinct_on:
35             self._distinct_on = [col.schema_column.identity for col in self._distinct_on]
36 
37     @property
38     def config(self):  # pragma: no cover
39         return ""
40 
41     @property
42     def greedy(self):  # pragma: no cover
43         return True
44 
45     @property
46     def name(self):  # pragma: no cover
47         return "Distinction"
48 
49     def execute(self) -> Generator[pyarrow.Table, None, None]:
50 
51         from opteryx.compiled.functions import HashSet
52         from opteryx.compiled.functions import distinct
53 
54         # We create a HashSet outside the distinct call, this allows us to pass
55         # the hash to each run of the distinct which means we don't need to concat
56         # all of the tables together to return a result.
57         # The Cython distinct is about 8x faster on a 10 million row dataset with
58         # approx 85k distinct entries (4.8sec vs 0.8sec) and faster on a 177 record
59         # dataset with 7 distinct entries.
60         # Being able to run morsel-by-morsel means if we have a LIMIT clause, we can
61         # limit processing
62         hash_set = HashSet()
63 
64         morsels = self._producers[0]  # type:ignore
65 
66         start = time.monotonic_ns()
67         for morsel in morsels.execute():
68             deduped, hash_set = distinct(
69                 morsel, columns=self._distinct_on, seen_hashes=hash_set, return_seen_hashes=True
70             )
71             if deduped.num_rows > 0:
72                 self.statistics.time_distincting += time.monotonic_ns() - start
73                 yield deduped
74                 start = time.monotonic_ns()
75
```

Path: `opteryx/__version__.py`
Content:
```
1 __build__ = 296
2 
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """
16 Store the version here so:
17 1) we don't load dependencies by storing it in __init__.py
18 2) we can import it in setup.py for the same reason
19 """
20 from enum import Enum  # isort: skip
21 
22 
23 class VersionStatus(Enum):
24     ALPHA = "alpha"
25     BETA = "beta"
26     RELEASE = "release"
27 
28 
29 _major = 0
30 _minor = 14
31 _revision = 0
32 _status = VersionStatus.ALPHA
33 
34 __author__ = "@joocer"
35 __version__ = f"{_major}.{_minor}.{_revision}" + (
36     f"-{_status.value}.{__build__}" if _status != VersionStatus.RELEASE else ""
37 )
38
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/opteryx/__version__.py b/opteryx/__version__.py
--- a/opteryx/__version__.py
+++ b/opteryx/__version__.py
@@ -1,4 +1,4 @@
-__build__ = 296
+__build__ = 298
 
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/opteryx/operators/distinct_node.py b/opteryx/operators/distinct_node.py
--- a/opteryx/operators/distinct_node.py
+++ b/opteryx/operators/distinct_node.py
@@ -29,10 +29,13 @@
 
 class DistinctNode(BasePlanNode):
     def __init__(self, properties: QueryProperties, **config):
+        from opteryx.compiled.functions import HashSet
+
         super().__init__(properties=properties)
         self._distinct_on = config.get("on")
         if self._distinct_on:
             self._distinct_on = [col.schema_column.identity for col in self._distinct_on]
+        self.hash_set = HashSet()
 
     @property
     def config(self):  # pragma: no cover
@@ -48,7 +51,6 @@
 
     def execute(self) -> Generator[pyarrow.Table, None, None]:
 
-        from opteryx.compiled.functions import HashSet
         from opteryx.compiled.functions import distinct
 
         # We create a HashSet outside the distinct call, this allows us to pass
@@ -59,16 +61,17 @@
         # dataset with 7 distinct entries.
         # Being able to run morsel-by-morsel means if we have a LIMIT clause, we can
         # limit processing
-        hash_set = HashSet()
 
         morsels = self._producers[0]  # type:ignore
 
-        start = time.monotonic_ns()
         for morsel in morsels.execute():
-            deduped, hash_set = distinct(
-                morsel, columns=self._distinct_on, seen_hashes=hash_set, return_seen_hashes=True
+            start = time.monotonic_ns()
+            deduped, self.hash_set = distinct(
+                morsel,
+                columns=self._distinct_on,
+                seen_hashes=self.hash_set,
+                return_seen_hashes=True,
             )
+            self.statistics.time_distincting += time.monotonic_ns() - start
             if deduped.num_rows > 0:
-                self.statistics.time_distincting += time.monotonic_ns() - start
                 yield deduped
-                start = time.monotonic_ns()

{"golden_diff": "diff --git a/opteryx/__version__.py b/opteryx/__version__.py\n--- a/opteryx/__version__.py\n+++ b/opteryx/__version__.py\n@@ -1,4 +1,4 @@\n-__build__ = 296\n+__build__ = 298\n \n # Licensed under the Apache License, Version 2.0 (the \"License\");\n # you may not use this file except in compliance with the License.\ndiff --git a/opteryx/operators/distinct_node.py b/opteryx/operators/distinct_node.py\n--- a/opteryx/operators/distinct_node.py\n+++ b/opteryx/operators/distinct_node.py\n@@ -29,10 +29,13 @@\n \n class DistinctNode(BasePlanNode):\n     def __init__(self, properties: QueryProperties, **config):\n+        from opteryx.compiled.functions import HashSet\n+\n         super().__init__(properties=properties)\n         self._distinct_on = config.get(\"on\")\n         if self._distinct_on:\n             self._distinct_on = [col.schema_column.identity for col in self._distinct_on]\n+        self.hash_set = HashSet()\n \n     @property\n     def config(self):  # pragma: no cover\n@@ -48,7 +51,6 @@\n \n     def execute(self) -> Generator[pyarrow.Table, None, None]:\n \n-        from opteryx.compiled.functions import HashSet\n         from opteryx.compiled.functions import distinct\n \n         # We create a HashSet outside the distinct call, this allows us to pass\n@@ -59,16 +61,17 @@\n         # dataset with 7 distinct entries.\n         # Being able to run morsel-by-morsel means if we have a LIMIT clause, we can\n         # limit processing\n-        hash_set = HashSet()\n \n         morsels = self._producers[0]  # type:ignore\n \n-        start = time.monotonic_ns()\n         for morsel in morsels.execute():\n-            deduped, hash_set = distinct(\n-                morsel, columns=self._distinct_on, seen_hashes=hash_set, return_seen_hashes=True\n+            start = time.monotonic_ns()\n+            deduped, self.hash_set = distinct(\n+                morsel,\n+                columns=self._distinct_on,\n+                seen_hashes=self.hash_set,\n+                return_seen_hashes=True,\n             )\n+            self.statistics.time_distincting += time.monotonic_ns() - start\n             if deduped.num_rows > 0:\n-                self.statistics.time_distincting += time.monotonic_ns() - start\n                 yield deduped\n-                start = time.monotonic_ns()\n", "issue": "\ud83e\udeb2stats for distinct incorrect\n### Thank you for taking the time to report a problem with Opteryx.\r\n_To help us to respond to your request we ask that you try to provide the below detail about the bug._\r\n\r\n**Describe the bug** _A clear and specific description of what the bug is. What the error, incorrect or unexpected behaviour was._\r\n\r\n\r\n**Expected behaviour** _A clear and concise description of what you expected to happen._\r\n\r\n\r\n**Sample Code/Statement** _If you can, please submit the SQL statement or Python code snippet, or a representative example using the sample datasets._\r\n\r\n~~~sql\r\n\r\n~~~\r\n\r\n**Additional context** _Add any other context about the problem here, for example what you have done to try to diagnose or workaround the problem._\r\n\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nDistinct Node\n\nThis is a SQL Query Execution Plan Node.\n\nThis Node eliminates duplicate records.\n\"\"\"\nimport time\nfrom typing import Generator\n\nimport pyarrow\nimport pyarrow.compute\n\nfrom opteryx.models import QueryProperties\nfrom opteryx.operators import BasePlanNode\n\n\nclass DistinctNode(BasePlanNode):\n    def __init__(self, properties: QueryProperties, **config):\n        super().__init__(properties=properties)\n        self._distinct_on = config.get(\"on\")\n        if self._distinct_on:\n            self._distinct_on = [col.schema_column.identity for col in self._distinct_on]\n\n    @property\n    def config(self):  # pragma: no cover\n        return \"\"\n\n    @property\n    def greedy(self):  # pragma: no cover\n        return True\n\n    @property\n    def name(self):  # pragma: no cover\n        return \"Distinction\"\n\n    def execute(self) -> Generator[pyarrow.Table, None, None]:\n\n        from opteryx.compiled.functions import HashSet\n        from opteryx.compiled.functions import distinct\n\n        # We create a HashSet outside the distinct call, this allows us to pass\n        # the hash to each run of the distinct which means we don't need to concat\n        # all of the tables together to return a result.\n        # The Cython distinct is about 8x faster on a 10 million row dataset with\n        # approx 85k distinct entries (4.8sec vs 0.8sec) and faster on a 177 record\n        # dataset with 7 distinct entries.\n        # Being able to run morsel-by-morsel means if we have a LIMIT clause, we can\n        # limit processing\n        hash_set = HashSet()\n\n        morsels = self._producers[0]  # type:ignore\n\n        start = time.monotonic_ns()\n        for morsel in morsels.execute():\n            deduped, hash_set = distinct(\n                morsel, columns=self._distinct_on, seen_hashes=hash_set, return_seen_hashes=True\n            )\n            if deduped.num_rows > 0:\n                self.statistics.time_distincting += time.monotonic_ns() - start\n                yield deduped\n                start = time.monotonic_ns()\n", "path": "opteryx/operators/distinct_node.py"}, {"content": "__build__ = 296\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nStore the version here so:\n1) we don't load dependencies by storing it in __init__.py\n2) we can import it in setup.py for the same reason\n\"\"\"\nfrom enum import Enum  # isort: skip\n\n\nclass VersionStatus(Enum):\n    ALPHA = \"alpha\"\n    BETA = \"beta\"\n    RELEASE = \"release\"\n\n\n_major = 0\n_minor = 14\n_revision = 0\n_status = VersionStatus.ALPHA\n\n__author__ = \"@joocer\"\n__version__ = f\"{_major}.{_minor}.{_revision}\" + (\n    f\"-{_status.value}.{__build__}\" if _status != VersionStatus.RELEASE else \"\"\n)\n", "path": "opteryx/__version__.py"}], "after_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nDistinct Node\n\nThis is a SQL Query Execution Plan Node.\n\nThis Node eliminates duplicate records.\n\"\"\"\nimport time\nfrom typing import Generator\n\nimport pyarrow\nimport pyarrow.compute\n\nfrom opteryx.models import QueryProperties\nfrom opteryx.operators import BasePlanNode\n\n\nclass DistinctNode(BasePlanNode):\n    def __init__(self, properties: QueryProperties, **config):\n        from opteryx.compiled.functions import HashSet\n\n        super().__init__(properties=properties)\n        self._distinct_on = config.get(\"on\")\n        if self._distinct_on:\n            self._distinct_on = [col.schema_column.identity for col in self._distinct_on]\n        self.hash_set = HashSet()\n\n    @property\n    def config(self):  # pragma: no cover\n        return \"\"\n\n    @property\n    def greedy(self):  # pragma: no cover\n        return True\n\n    @property\n    def name(self):  # pragma: no cover\n        return \"Distinction\"\n\n    def execute(self) -> Generator[pyarrow.Table, None, None]:\n\n        from opteryx.compiled.functions import distinct\n\n        # We create a HashSet outside the distinct call, this allows us to pass\n        # the hash to each run of the distinct which means we don't need to concat\n        # all of the tables together to return a result.\n        # The Cython distinct is about 8x faster on a 10 million row dataset with\n        # approx 85k distinct entries (4.8sec vs 0.8sec) and faster on a 177 record\n        # dataset with 7 distinct entries.\n        # Being able to run morsel-by-morsel means if we have a LIMIT clause, we can\n        # limit processing\n\n        morsels = self._producers[0]  # type:ignore\n\n        for morsel in morsels.execute():\n            start = time.monotonic_ns()\n            deduped, self.hash_set = distinct(\n                morsel,\n                columns=self._distinct_on,\n                seen_hashes=self.hash_set,\n                return_seen_hashes=True,\n            )\n            self.statistics.time_distincting += time.monotonic_ns() - start\n            if deduped.num_rows > 0:\n                yield deduped\n", "path": "opteryx/operators/distinct_node.py"}, {"content": "__build__ = 298\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"\nStore the version here so:\n1) we don't load dependencies by storing it in __init__.py\n2) we can import it in setup.py for the same reason\n\"\"\"\nfrom enum import Enum  # isort: skip\n\n\nclass VersionStatus(Enum):\n    ALPHA = \"alpha\"\n    BETA = \"beta\"\n    RELEASE = \"release\"\n\n\n_major = 0\n_minor = 14\n_revision = 0\n_status = VersionStatus.ALPHA\n\n__author__ = \"@joocer\"\n__version__ = f\"{_major}.{_minor}.{_revision}\" + (\n    f\"-{_status.value}.{__build__}\" if _status != VersionStatus.RELEASE else \"\"\n)\n", "path": "opteryx/__version__.py"}]}