ericsink / SQLitePCL.raw

A Portable Class Library (PCL) for low-level (raw) access to SQLite
Apache License 2.0
512 stars 106 forks source link

Handle zero-length `Span` inputs for `sqlite3_bind_text*` #558

Closed nil4 closed 7 months ago

nil4 commented 8 months ago

Same as sqlite3_bind_blob, the SQLite C APIs sqlite3_bind_text* require the data pointer argument to be non-null to actually accept zero-length input. Otherwise, when a null data pointer is passed, the explicit length is ignored and a SQLITE_NULL value is bound instead.

This PR updates sqlite3_bind_text and sqlite3_bind_text16 to handle zero-length ReadOnlySpans, by substituting a valid pointer for the zero-length case.

The generated sqlite3_bind_blob code already handled this scenario by allocating a new byte[] for each call e.g. at:

https://github.com/ericsink/SQLitePCL.raw/blob/9c66b4f618d9d6831e83c16a8036daea83df4ddb/src/providers/provider.tt#L1586-L1595

This PR proposes a potentially lower-overhead solution (passing the address of a local) for both sqlite3_bind_text* and sqlite3_bind_blob, as suggested by Span<T> usage Rule #9:

In the previous example, pbData can be null if, for example, the input span is empty. If the exported method absolutely requires that pbData be non-null, even if cbData is 0, the method can be implemented as follows

These changes address the sqlite3_bind_text* functions behavior when called with empty ReadOnlySpan.

Fixes https://github.com/ericsink/SQLitePCL.raw/issues/557

ericsink commented 7 months ago

I made a code change similar to this PR, but keeping the explicit checks for Length == 0. Thanks!