Repository: geopandas/geopandas

Issue:
ENH: More descriptive error if duplicate geometry column is detected
I was dealing with a vague error for a while until I found out that the problem was caused by a duplicate `geom` column (the query was quite complex with a lot of CTES and joins, and it ended with a `SELECT * FROM...` so it took a while to figure out what was happening).

Apparently, pandas and geopandas are ok with returning duplicate column names, this is confirmed by the fact that the following statements work and return a Geo/DataFrame:

```python
pd.read_sql("select 0 as foo, 0 as foo, ST_MakePoint(0, 0) as geom", engine)
gpd.read_postgis("select 0 as foo, 0 as foo, ST_MakePoint(0, 0) as geom", engine)
```

Trouble happens however if the geometry column is duplicated:

```python
gpd.read_postgis("select ST_MakePoint(0, 0) as geom, ST_MakePoint(0, 0) as geom", engine)
```

This is totally understandable because of the special nature of the geometry column. However, the error is pretty vague:

```python
Traceback (most recent call last):
  File "/home/isaac/pycharm-2021.3.3/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "/home/isaac/PycharmProjects/microgrid-support/venv/lib/python3.8/site-packages/geopandas/io/sql.py", line 163, in _read_postgis
    return _df_to_geodf(df, geom_col=geom_col, crs=crs)
  File "/home/isaac/PycharmProjects/microgrid-support/venv/lib/python3.8/site-packages/geopandas/io/sql.py", line 81, in _df_to_geodf
    if isinstance(geoms.iat[0], bytes):
  File "/home/isaac/PycharmProjects/microgrid-support/venv/lib/python3.8/site-packages/pandas/core/indexing.py", line 2221, in __getitem__
    return self.obj._get_value(*key, takeable=self._takeable)
TypeError: _get_value() missing 1 required positional argument: 'col'
```

There is hardly any indication that it even has anything to do with the geometry column, and the final error is just a generic `TypeError`.

I propose that this case should be caught and geopandas should check for this problem and raise an error if detected, probably around [here](https://github.com/geopandas/geopandas/blob/main/geopandas/io/sql.py#L81).

I can make a PR for this if you agree.


Discussion:
Nice catch and diagnostics!

> I can make a PR for this if you agree.

Yes please. Note that we have currently a limited capacity so the review and merge may take some time.

Resolving patch:
diff --git a/geopandas/io/sql.py b/geopandas/io/sql.py
--- a/geopandas/io/sql.py
+++ b/geopandas/io/sql.py
@@ -65,6 +65,12 @@ def _df_to_geodf(df, geom_col="geom", crs=None):
     if geom_col not in df:
         raise ValueError("Query missing geometry column '{}'".format(geom_col))
 
+    if df.columns.to_list().count(geom_col) > 1:
+        raise ValueError(
+            f"Duplicate geometry column '{geom_col}' detected in SQL query output. Only"
+            "one geometry column is allowed."
+        )
+
     geoms = df[geom_col].dropna()
 
     if not geoms.empty:


Test patch:
diff --git a/geopandas/io/tests/test_sql.py b/geopandas/io/tests/test_sql.py
--- a/geopandas/io/tests/test_sql.py
+++ b/geopandas/io/tests/test_sql.py
@@ -697,3 +697,14 @@ def test_append_with_different_crs(self, engine_postgis, df_nybb):
         # Should raise error when appending
         with pytest.raises(ValueError, match="CRS of the target table"):
             write_postgis(df_nybb2, con=engine, name=table, if_exists="append")
+
+    def test_duplicate_geometry_column_fails(self, engine_postgis):
+        """
+        Tests that a ValueError is raised if an SQL query returns two geometry columns.
+        """
+        engine = engine_postgis
+
+        sql = "select ST_MakePoint(0, 0) as geom, ST_MakePoint(0, 0) as geom;"
+
+        with pytest.raises(ValueError):
+            read_postgis(sql, engine, geom_col="geom")