geographika · GitHub

This PR will only use the SQLWCHAR versions of the ODBC API when on Windows and ICONV is present. With this change I was able to connect successfully from an Ubuntu machine with MapServer installed to a SQL Server 19 database with MapServer.

Without this change there was an initial error '[unixODBC][Driver Manager]Data source name not found and no default driver specified' as the connection string was getting corrupted.

Without the other changes the SQL statements themselves were getting corrupted, and the SQL Server Profiler showed SQL requests similar to those below:

SLC GO]'em,ovr(aca(6,[betd)'d RM
      (
      EET*FO do.RI_EWR_EMN_IE
      )
      stlWEEGO.TnescsGoer:SGoFoTx(PLGN(7214 1312,1956586.8892. 6053,7214 6053,7214 1312)'25)

With this PR it is now possible to connect successfully:

sudo ACCEPT_EULA=Y apt install -y msodbcsql18
# check registered drivers
odbcinst -q -d
# [ODBC Driver 18 for SQL Server]
iusql -v "Driver={ODBC Driver 18 for SQL Server};Server=MyServer;Database=MyDatabase;UID=user;PWD=password123;Encrypt=yes;TrustServerCertificate=yes;"
map2img -m test.map -conf /vagrant/etc/mapserver-sample.conf

mapserver-sample.conf needs to point to the plugin:

  PLUGINS
    "mssql" "/vagrant/build_vagrant/libmsplugin_mssql2008.sol"
  END

And the test.map :


LAYER
...
        PLUGIN "mssql"
        PROCESSING "CLOSE_CONNECTION=DEFER"
        CONNECTION "Driver={ODBC Driver 18 for SQL Server};Server=MyServer;Database=MyDatabase;UID=user;PWD=password123;Encrypt=yes;TrustServerCertificate=yes;"

For reference, below are the relevant links to the different encoding issues relating to the ODBC Driver.

https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/known-issues-in-this-version-of-the-driver?view=sql-server-ver17&viewFallbackFrom=sql-server-ver18

If the client encoding is UTF-8, the driver manager doesn't always correctly convert from UTF-8 to UTF-16. Currently, data corruption occurs when one or more characters in the string aren't valid UTF-8 characters. ASCII characters are mapped correctly. The driver manager attempts this conversion when calling the SQLCHAR versions of the ODBC API (for example, SQLDriverConnectA). The driver manager won't attempt this conversion when calling the SQLWCHAR versions of the ODBC API (for example, SQLDriverConnectW).

https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/frequently-asked-questions-faq-for-odbc-linux?view=sql-server-ver17&viewFallbackFrom=sql-server-ver18#frequently-asked-questions

Which Unicode encoding should an application use?
UTF-8 for SQL_CHAR data and UTF-16 for SQL_WCHAR data. Depending on the system locale and driver version, non-UTF-8 data in one of several encodings may also be supported.

https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/programming-guidelines?view=sql-server-ver17&viewFallbackFrom=sql-server-ver18#character-set-support

Therefore, in a typical Linux or macOS environment where the encoding is UTF-8, users of ODBC Driver 17 upgrading from 13 or 13.1 won't observe any differences. However, applications that use a non-UTF-8 encoding in the above list via setlocale() need to use that encoding for data to/from the driver instead of UTF-8.
SQLWCHAR data must be UTF-16LE (Little Endian).

Related PR: #6150

Read the original on github.com ↗