Description
What is the bug?
I compiled GDAL 3.8.5 with support for the PGeo
driver on an M1 MacOS
, but when I ran the command ogrinfo --debug on -if PGeo 640122HLX_2006Y00_SV050_P.mdb
, I received the following debug information:
ODBC: Declaration of Microsoft Access Driver found in /etc/odbcinst.ini
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: ... failed:
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ="640122HLX_2006Y00_SV050_P.mdb")
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ="640122HLX_2006Y00_SV050_P.mdb")
ODBC: ... failed:
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
PGEO: SELECT on GDB_GeomColumns fails, perhaps not a personal geodatabase?
ODBC: SQLDisconnect()
Additionally, the program becomes unresponsive and cannot be stopped, while consuming 100% CPU on a single core (possibly due to an infinite loop?).
One particularly valuable piece of information was: 'PGEO: SELECT on GDB_GeomColumns fails, perhaps not a personal geodatabase?'
I attempted to trace the GDAL source code and by adding debug information, it seems that the issue occurs when executing the following SQL statement:
// /ogr/ogrsf_frmts/pgeo/ogrpgeodatasource.cpp
std::vector<char **> apapszGeomColumns;
CPLODBCStatement oStmt(&oSession);
oStmt.Append(
"SELECT TableName, FieldName, ShapeType, ExtentLeft, ExtentRight, "
"ExtentBottom, ExtentTop, SRID, HasZ, HasM FROM GDB_GeomColumns");
if (!oStmt.ExecuteSQL())
{
CPLDebug("PGEO",
"SELECT on GDB_GeomColumns fails, perhaps not a personal "
"geodatabase?\n%s",
oSession.GetLastError());
return FALSE;
}
Continuing the trace, it appears that the SQLExecDirect
method returns -2
, but no valuable error information is captured.
As I am not very familiar with C++, I am unable to further trace the issue. It is clear, however, that the SQLExecDirect
method is from unixODBC
(if I understand correctly).
// /port/cpl_odbc.cpp
// SQL_NTS=-3 is a valid value for SQLExecDirect.
// coverity[negative_returns]
if (Failed(SQLExecDirect(
m_hStmt, reinterpret_cast<SQLCHAR *>(m_pszStatement), SQL_NTS)))
return FALSE;
return CollectResultsInfo();
Furthermore, I tried executing the problematic SQL statement directly through unixODBC
and encountered no issues. I configured the mdb file in odbc.ini
and used the isql
command to read it as follows:
➜ testmdb isql -v MyTestAccessDB
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| echo [string] |
| quit |
| |
+---------------------------------------+
SQL> SELECT TableName, FieldName, ShapeType, ExtentLeft, ExtentRight, ExtentBottom, ExtentTop, SRID, HasZ, HasM FROM GDB_GeomColumns
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+-----------+------------+-------------+-----------+------------+-----+-----+
| TableName | FieldName | ShapeType | ExtentLeft| ExtentRight| ExtentBottom| ExtentTop | SRID | HasZ| HasM|
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+-----------+------------+-------------+-----------+------------+-----+-----+
| GDB_Items | Shape | 4 | 106.062013| 106.121651 | 38.832024999| 38.855929 | 1 | 0 | 0 |
| MPID | Shape | 4 | 106.062013| 106.1216514| 38.832024971| 38.8559290| 2 | 0 | 0 |
| MBII | Shape | 4 | 106.062013| 106.1216514| 38.832024971| 38.8559290| 2 | 0 | 0 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+-----------+------------+-------------+-----------+------------+-----+-----+
SQLRowCount returns 3
3 rows fetched
I am confident that there is no issue with the mdb file itself, as I not only compiled GDAL on my machine but also added the PGeo
driver to the official ARM version of the GDAL Docker image
. I then executed the same command against the same mdb file within the container and obtained the correct results. The output was as follows:
ODBC: Declaration of Microsoft Access Driver found in /etc/odbcinst.ini
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: ... failed:
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ="640122HLX_2006Y00_SV050_P.mdb")
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ="640122HLX_2006Y00_SV050_P.mdb")
ODBC: ... failed:
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: CatalogNameL: (null)
Schema name: (null)
PGeo: MPID: no primary key
PGeo: MBII: no primary key
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: ... failed:
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ="640122HLX_2006Y00_SV050_P.mdb")
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ="640122HLX_2006Y00_SV050_P.mdb")
ODBC: ... failed:
ODBC: SQLDisconnect()
ODBC: EstablishSession(DRIVER=Microsoft Access Driver (*.mdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: SQLDriverConnect(DRIVER=Microsoft Access Driver (*.mdb);DBQ=640122HLX_2006Y00_SV050_P.mdb)
ODBC: CatalogNameL: (null)
Schema name: (null)
PGeo: MPID: no primary key
PGeo: MBII: no primary key
GDAL: GDALOpen(640122HLX_2006Y00_SV050_P.mdb, this=0xaaaae6417eb0) succeeds as PGeo.
INFO: Open of `640122HLX_2006Y00_SV050_P.mdb'
using driver `PGeo' successful.
OGR: GetLayerCount() = 2
1: MPID (Multi Polygon)
2: MBII (Multi Polygon)
ODBC: SQLDisconnect()
GDAL: GDALClose(640122HLX_2006Y00_SV050_P.mdb, this=0xaaaae6417eb0)
Steps to reproduce the issue
Install unixODBC, mdbtools, etc., compile GDAL 3.8.5, and execute the command: ogrinfo --debug on -if PGeo xxx.mdb. The compilation command is as follows:
cd gdal-3.8.5
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/Users/yuziqun/main/software/gdal-3.8.5-nokml -DCMAKE_INSTALL_RPATH=/Users/yuziqun/main/software/gdal-3.8.5-nokml/lib -DBUILD_PYTHON_BINDINGS=OFF -DGDAL_USE_LIBKML=OFF -DCMAKE_DISABLE_FIND_PACKAGE_Arrow=ON ..
cmake --build . -- -j6
cmake --build . --target install
Versions and provenance
M1 pro MacOS 14.4.1
➜ build ogrinfo --version
GDAL 3.8.5, released 2024/04/02
➜ build isql --version
unixODBC 2.3.12
➜ build mdb-ver --version
mdbtools v1.0.0
Additional context
No response