API
C
Description
The engine supports the BLOB type end-to-end (LBUG_BLOB exists in the type enum, and blob results can be read back), but the C API has no way to construct a BLOB value. As a result, it is impossible to bind a BLOB as a query parameter from any binding built on the C API.
Evidence
The value-creation functions in src/c_api/value.cpp cover every variable-size type except BLOB:
null, null_with_data_type, default, bool, int8/16/32/64, uint8/16/32/64,
int128, float, double, decimal, internal_id, date, timestamp(+ns/ms/sec/tz),
interval, string, json, uuid, list, struct, map
- Reading works:
lbug_value_get_blob exists and correctly returns the raw bytes from a BLOB value. https://github.com/LadybugDB/ladybug/blob/main/src/c_api/value.cpp
- There is no
lbug_value_create_blob (no counterpart to lbug_value_get_blob), and no lbug_value_set_* mutator that could fill in a lbug_value_create_default(LBUG_BLOB) placeholder either.
lbug_prepared_statement_bind_value requires an already-constructed lbug_value, so there is no entry point to bind blob bytes to a $param.
test/c_api/prepared_statement_test.cpp has no blob binding test either.
The docs do not document this limitation anywhere (the prepared-statements page shows only STRING/INT64/LIST examples and never enumerates the bindable types), so I'm filing this for tracking.
Suggested API
Mirror the existing getter:
LBUG_C_API lbug_value* lbug_value_create_blob(const uint8_t* data, uint64_t length);
Implementation sketch (C++ side of the C API):
auto* c_value = (lbug_value*)calloc(1, sizeof(lbug_value));
c_value->_value = new Value(LogicalType::BLOB(),
std::string(reinterpret_cast<const char*>(data), length));
return c_value;
This makes the bound value exactly BLOB-typed, so lbug_prepared_statement_bind_value hits the exact-type match path with no string cast involved. Also worth adding while touching the file, for consistency: lbug_value_create_uuid already exists, so BLOB is the only missing primitive constructor.
Related minor gap: UUID cannot be created from bytes
lbug_value_create_uuid(const char*) only accepts the string form of a UUID (it parses through UUID::fromCString). There is no constructor that takes the raw 16 bytes, so callers who hold a binary UUID (e.g. received from another system) must format it into the standard string form first.
LBUG_C_API lbug_value* lbug_value_create_uuid_from_bytes(const uint8_t data[16]);
API
C
Description
The engine supports the BLOB type end-to-end (
LBUG_BLOBexists in the type enum, and blob results can be read back), but the C API has no way to construct a BLOB value. As a result, it is impossible to bind a BLOB as a query parameter from any binding built on the C API.Evidence
The value-creation functions in
src/c_api/value.cppcover every variable-size type except BLOB:lbug_value_get_blobexists and correctly returns the raw bytes from a BLOB value. https://github.com/LadybugDB/ladybug/blob/main/src/c_api/value.cpplbug_value_create_blob(no counterpart tolbug_value_get_blob), and nolbug_value_set_*mutator that could fill in albug_value_create_default(LBUG_BLOB)placeholder either.lbug_prepared_statement_bind_valuerequires an already-constructedlbug_value, so there is no entry point to bind blob bytes to a$param.test/c_api/prepared_statement_test.cpphas no blob binding test either.The docs do not document this limitation anywhere (the prepared-statements page shows only STRING/INT64/LIST examples and never enumerates the bindable types), so I'm filing this for tracking.
Suggested API
Mirror the existing getter:
Implementation sketch (C++ side of the C API):
This makes the bound value exactly BLOB-typed, so
lbug_prepared_statement_bind_valuehits the exact-type match path with no string cast involved. Also worth adding while touching the file, for consistency:lbug_value_create_uuidalready exists, so BLOB is the only missing primitive constructor.Related minor gap: UUID cannot be created from bytes
lbug_value_create_uuid(const char*)only accepts the string form of a UUID (it parses throughUUID::fromCString). There is no constructor that takes the raw 16 bytes, so callers who hold a binary UUID (e.g. received from another system) must format it into the standard string form first.