DataAction / AdoNetCore.AseClient

AdoNetCore.AseClient - a .NET Core DB Provider for SAP ASE
Apache License 2.0
108 stars 45 forks source link

Discrepancy in handling of null vs zero-length strings #35

Closed senseibaka closed 6 years ago

senseibaka commented 6 years ago

Due to the nature of the TDS protocol, there is no difference between null and a zero-length string.

This is because strings are transmitted as length-prefixed, with no separate bit to signal a null value.

So, null is transmitted as "this string is 0 bytes long" and, empty is transmitted as "this string is 0 bytes long".

Therefore, ASE interprets "this string is 0 bytes long" as null, regardless of the caller's intent.

Currently, our driver doesn't make the distinction between the two, which can result in insertion errors ("Attempt to insert null value into column 'foo'").


The SAP Driver has the following Ribo output:

PARAMFMT Token (0xEC); variable length.
  ...
  Param 1
    User Type [4]:              0
    Data Type [1]:              CHAR
    Length [1]:                 255
    Locale Length [1]:          0
PARAMS Token (0xD7); variable length.
  Param 1
    Length [1]:                 1
    Param data [1]:             " " (0x20)

So as can be seen, to skirt this issue we should send zero-length strings as single spaces.

Corollary: look at what the SAP driver does to these values when they're being read out. Does the driver receive a single space and interpret it as string.Empty?

senseibaka commented 6 years ago

It appears that the SAP driver leaves the spaces alone (i.e. it doesn't trim results) when selecting them back out. Will do some further tests, but it looks like this is purely to differentiate null and empty strings when sending to the server.