Repository: modin-project/modin

Issue:
Reading from postgres SQL databases causes a syntax error.
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: MacOS Monterey 12.2.1
- **Modin version** (`modin.__version__`): Latest source code (past latest release version 0.13.2)
- **Python version**: 3.9.9
- **Code we can use to reproduce**: You can use this code, which reads from a publicly available postgres server, which worked in manual tests as of #3629:

```python
import modin.pandas as pd
from modin.core.io.sql.connection import ModinDatabaseConnection
con = ModinDatabaseConnection(
    'psycopg2',
    host='hh-pgsql-public.ebi.ac.uk',
    dbname='pfmegrnargs',
    user='reader',
    password='NWDMCE5xdipIjRrp')
df = pd.read_sql("SELECT * FROM rnc_database",
     		 con,
		 index_col=None,
		 coerce_float=True,
		 params=None,
		 parse_dates=None,
		 chunksize=None)
```

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
#4279, which enabled reading from SQL server, broke reading from postgres SQL databases, which require an alias for subqueries in the FROM clause. The fix is to add an alias [here](https://github.com/modin-project/modin/blob/e67db1dd3ee448eec23a05ffdb3ca38a2b2b709e/modin/db_conn.py#L162). We should also add tests to make sure that such a regression doesn't happen again for postgres, as we did in #979.

### Source code / logs
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->

Here's the end of the stack trace caused by the code snippet above:

<details>
<summary>Show stack trace.</summary>

```
ray::_deploy_ray_func() (pid=48106, ip=127.0.0.1)
  File "/Users/maheshvashishtha/modin/modin/core/execution/ray/common/task_wrapper.py", line 42, in _deploy_ray_func
    return func(**args)
  File "/Users/maheshvashishtha/modin/modin/core/storage_formats/pandas/parsers.py", line 711, in parse
    df = pandas.read_sql(sql, con, index_col=index_col, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/pandas/io/sql.py", line 566, in read_sql
    return pandas_sql.read_query(
  File "/usr/local/lib/python3.9/site-packages/pandas/io/sql.py", line 2080, in read_query
    cursor = self.execute(*args)
  File "/usr/local/lib/python3.9/site-packages/pandas/io/sql.py", line 2032, in execute
    raise ex from exc
pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT * FROM (SELECT * FROM rnc_database) LIMIT 3 OFFSET 30': subquery in FROM must have an alias
LINE 1: SELECT * FROM (SELECT * FROM rnc_database) LIMIT 3 OFFSET 30
```

</details>


Discussion:

Resolving patch:
diff --git a/modin/config/envvars.py b/modin/config/envvars.py
--- a/modin/config/envvars.py
+++ b/modin/config/envvars.py
@@ -453,6 +453,13 @@ class TestReadFromSqlServer(EnvironmentVariable, type=bool):
     default = False
 
 
+class TestReadFromPostgres(EnvironmentVariable, type=bool):
+    """Set to true to test reading from Postgres."""
+
+    varname = "MODIN_TEST_READ_FROM_POSTGRES"
+    default = False
+
+
 def _check_vars():
     """
     Check validity of environment variables.
diff --git a/modin/db_conn.py b/modin/db_conn.py
--- a/modin/db_conn.py
+++ b/modin/db_conn.py
@@ -159,5 +159,5 @@ def partition_query(self, query, limit, offset):
                 + f" OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"
             )
             if self._dialect_is_microsoft_sql()
-            else f"SELECT * FROM ({query}) LIMIT {limit} OFFSET {offset}"
+            else f"SELECT * FROM ({query}) AS _ LIMIT {limit} OFFSET {offset}"
         )


Test patch:
diff --git a/modin/pandas/test/test_io.py b/modin/pandas/test/test_io.py
--- a/modin/pandas/test/test_io.py
+++ b/modin/pandas/test/test_io.py
@@ -28,6 +28,7 @@
     Engine,
     StorageFormat,
     IsExperimental,
+    TestReadFromPostgres,
     TestReadFromSqlServer,
 )
 from modin.utils import to_pandas
@@ -1868,6 +1869,27 @@ def test_read_sql_from_sql_server(self):
         pandas_df = pandas.read_sql(query, sqlalchemy_connection_string)
         df_equals(modin_df, pandas_df)
 
+    @pytest.mark.skipif(
+        not TestReadFromPostgres.get(),
+        reason="Skip the test when the postgres server is not set up.",
+    )
+    def test_read_sql_from_postgres(self):
+        table_name = "test_1000x256"
+        query = f"SELECT * FROM {table_name}"
+        connection = "postgresql://sa:Strong.Pwd-123@localhost:2345/postgres"
+        pandas_df_to_read = pandas.DataFrame(
+            np.arange(
+                1000 * 256,
+            ).reshape(1000, 256)
+        ).add_prefix("col")
+        pandas_df_to_read.to_sql(table_name, connection, if_exists="replace")
+        modin_df = pd.read_sql(
+            query,
+            ModinDatabaseConnection("psycopg2", connection),
+        )
+        pandas_df = pandas.read_sql(query, connection)
+        df_equals(modin_df, pandas_df)
+
     def test_invalid_modin_database_connections(self):
         with pytest.raises(UnsupportedDatabaseException):
             ModinDatabaseConnection("unsupported_database")