Repository: modin-project/modin

Issue:
BUG: HDK: Unable to merge frames by columns of type float
### Modin version checks

- [X] I have checked that this issue has not already been reported.

- [X] I have confirmed this bug exists on the latest released version of Modin.

- [X] I have confirmed this bug exists on the main branch of Modin. (In order to do this you can follow [this guide](https://modin.readthedocs.io/en/stable/getting_started/installation.html#installing-from-the-github-master-branch).)


### Reproducible Example

```python
import modin.pandas as pd

df1 = pd.DataFrame({"A": [1.0, 2.0] * 1000})
df2 = pd.DataFrame({"A": [1, 3] * 1000})
df = df1.merge(df2, on="A")
print(df)
```


### Issue Description

The code above fails with the error:
```python-traceback
hdk_worker.py", line 76, in _executeRelAlgJson
    res = rel_alg_executor.execute()
  File "_sql.pyx", line 126, in pyhdk._sql.RelAlgExecutor.execute
RuntimeError: Hash join failed, reason(s): Cannot apply hash join to inner column type FP64 | Cannot fall back to loop join for non-trivial inner table size
```
The root cause - https://github.com/intel-ai/hdk/issues/424

### Expected Behavior

Merge by floating point numbers should be supported.

### Error Logs

<details>

```python-traceback

Replace this line with the error backtrace (if applicable).

```

</details>


### Installed Versions

<details>

Replace this line with the output of pd.show_versions()

</details>



Discussion:

Resolving patch:
diff --git a/modin/experimental/core/execution/native/implementations/hdk_on_native/dataframe/dataframe.py b/modin/experimental/core/execution/native/implementations/hdk_on_native/dataframe/dataframe.py
--- a/modin/experimental/core/execution/native/implementations/hdk_on_native/dataframe/dataframe.py
+++ b/modin/experimental/core/execution/native/implementations/hdk_on_native/dataframe/dataframe.py
@@ -29,6 +29,9 @@
     get_dtype,
     is_list_like,
     is_bool_dtype,
+    is_string_dtype,
+    is_any_int_dtype,
+    is_datetime64_dtype,
     is_categorical_dtype,
 )
 
@@ -955,6 +958,18 @@ def join(
         orig_right_on = right_on
         left, left_on = check_cols_to_join("left_on", self, left_on)
         right, right_on = check_cols_to_join("right_on", other, right_on)
+        for left_col, right_col in zip(left_on, right_on):
+            left_dt = self._dtypes[left_col]
+            right_dt = other._dtypes[right_col]
+            if not (
+                (is_any_int_dtype(left_dt) and is_any_int_dtype(right_dt))
+                or (is_string_dtype(left_dt) and is_string_dtype(right_dt))
+                or (is_datetime64_dtype(left_dt) and is_datetime64_dtype(right_dt))
+                or (is_categorical_dtype(left_dt) and is_categorical_dtype(right_dt))
+            ):
+                raise NotImplementedError(
+                    f"Join on columns of '{left_dt}' and '{right_dt}' dtypes"
+                )
 
         # If either left_on or right_on has been changed, it means that there
         # are index columns in the list. Joining by index in this case.


Test patch:
diff --git a/modin/experimental/core/execution/native/implementations/hdk_on_native/test/test_dataframe.py b/modin/experimental/core/execution/native/implementations/hdk_on_native/test/test_dataframe.py
--- a/modin/experimental/core/execution/native/implementations/hdk_on_native/test/test_dataframe.py
+++ b/modin/experimental/core/execution/native/implementations/hdk_on_native/test/test_dataframe.py
@@ -1588,6 +1588,52 @@ def merge(df, lib, iterations, **kwargs):
                 iterations=i,
             )
 
+    def test_merge_float(self):
+        def merge(df, df2, on_columns, **kwargs):
+            return df.merge(df2, on=on_columns)
+
+        run_and_compare(
+            merge,
+            data={"A": [1, 2] * 1000},
+            data2={"A": [1.0, 3.0] * 1000},
+            on_columns="A",
+            force_lazy=False,
+        )
+
+    def test_merge_categorical(self):
+        def merge(df, df2, on_columns, **kwargs):
+            return df.merge(df2, on=on_columns)
+
+        run_and_compare(
+            merge,
+            data={"A": [1, 2] * 1000},
+            data2={"A": [1.0, 3.0] * 1000},
+            on_columns="A",
+            constructor_kwargs={"dtype": "category"},
+            comparator=lambda df1, df2: df_equals(df1.astype(float), df2.astype(float)),
+        )
+
+    def test_merge_date(self):
+        def merge(df, df2, on_columns, **kwargs):
+            return df.merge(df2, on=on_columns)
+
+        run_and_compare(
+            merge,
+            data={
+                "A": [
+                    pd.Timestamp("2023-01-01"),
+                    pd.Timestamp("2023-01-02"),
+                ]
+            },
+            data2={
+                "A": [
+                    pd.Timestamp("2023-01-01"),
+                    pd.Timestamp("2023-01-03"),
+                ]
+            },
+            on_columns="A",
+        )
+
 
 class TestBinaryOp:
     data = {