//===----------------------------------------------------------------------===// // DuckDB // // duckdb/main/capi/cast/utils.hpp // // //===----------------------------------------------------------------------===// #pragma once #include "duckdb/main/capi/capi_internal.hpp" #include "duckdb/common/operator/cast_operators.hpp" #include "duckdb/common/operator/string_cast.hpp" #include "duckdb/common/operator/decimal_cast_operators.hpp" namespace duckdb { //===--------------------------------------------------------------------===// // Unsafe Fetch (for internal use only) //===--------------------------------------------------------------------===// template T UnsafeFetchFromPtr(void *pointer) { return *((T *)pointer); } template void *UnsafeFetchPtr(duckdb_result *result, idx_t col, idx_t row) { D_ASSERT(row < result->__deprecated_row_count); return (void *)&(((T *)result->__deprecated_columns[col].__deprecated_data)[row]); } template T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) { return UnsafeFetchFromPtr(UnsafeFetchPtr(result, col, row)); } //===--------------------------------------------------------------------===// // Fetch Default Value //===--------------------------------------------------------------------===// struct FetchDefaultValue { template static T Operation() { return 0; } }; template <> duckdb_decimal FetchDefaultValue::Operation(); template <> date_t FetchDefaultValue::Operation(); template <> dtime_t FetchDefaultValue::Operation(); template <> timestamp_t FetchDefaultValue::Operation(); template <> interval_t FetchDefaultValue::Operation(); template <> char *FetchDefaultValue::Operation(); template <> duckdb_string FetchDefaultValue::Operation(); template <> duckdb_blob FetchDefaultValue::Operation(); //===--------------------------------------------------------------------===// // String Casts //===--------------------------------------------------------------------===// template struct FromCStringCastWrapper { template static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) { string_t input(input_str); return OP::template Operation(input, result); } }; template struct ToCStringCastWrapper { template static bool Operation(SOURCE_TYPE input, RESULT_TYPE &result) { Vector result_vector(LogicalType::VARCHAR, nullptr); auto result_string = OP::template Operation(input, result_vector); auto result_size = result_string.GetSize(); auto result_data = result_string.GetData(); char *allocated_data = char_ptr_cast(duckdb_malloc(result_size + 1)); memcpy(allocated_data, result_data, result_size); allocated_data[result_size] = '\0'; result.data = allocated_data; result.size = result_size; return true; } }; //===--------------------------------------------------------------------===// // Blob Casts //===--------------------------------------------------------------------===// struct FromCBlobCastWrapper { template static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) { return false; } }; template <> bool FromCBlobCastWrapper::Operation(duckdb_blob input, duckdb_string &result); template RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) { RESULT_TYPE result_value; try { if (!OP::template Operation(UnsafeFetch(result, col, row), result_value)) { return FetchDefaultValue::Operation(); } } catch (...) { return FetchDefaultValue::Operation(); } return result_value; } } // namespace duckdb bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row); bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row);