1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/main/capi/cast/utils.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/main/capi/capi_internal.hpp"
12#include "duckdb/common/operator/cast_operators.hpp"
13#include "duckdb/common/operator/string_cast.hpp"
14#include "duckdb/common/operator/decimal_cast_operators.hpp"
15
16namespace duckdb {
17
18//===--------------------------------------------------------------------===//
19// Unsafe Fetch (for internal use only)
20//===--------------------------------------------------------------------===//
21template <class T>
22T UnsafeFetchFromPtr(void *pointer) {
23 return *((T *)pointer);
24}
25
26template <class T>
27void *UnsafeFetchPtr(duckdb_result *result, idx_t col, idx_t row) {
28 D_ASSERT(row < result->__deprecated_row_count);
29 return (void *)&(((T *)result->__deprecated_columns[col].__deprecated_data)[row]);
30}
31
32template <class T>
33T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) {
34 return UnsafeFetchFromPtr<T>(UnsafeFetchPtr<T>(result, col, row));
35}
36
37//===--------------------------------------------------------------------===//
38// Fetch Default Value
39//===--------------------------------------------------------------------===//
40struct FetchDefaultValue {
41 template <class T>
42 static T Operation() {
43 return 0;
44 }
45};
46
47template <>
48duckdb_decimal FetchDefaultValue::Operation();
49template <>
50date_t FetchDefaultValue::Operation();
51template <>
52dtime_t FetchDefaultValue::Operation();
53template <>
54timestamp_t FetchDefaultValue::Operation();
55template <>
56interval_t FetchDefaultValue::Operation();
57template <>
58char *FetchDefaultValue::Operation();
59template <>
60duckdb_string FetchDefaultValue::Operation();
61template <>
62duckdb_blob FetchDefaultValue::Operation();
63
64//===--------------------------------------------------------------------===//
65// String Casts
66//===--------------------------------------------------------------------===//
67template <class OP>
68struct FromCStringCastWrapper {
69 template <class SOURCE_TYPE, class RESULT_TYPE>
70 static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
71 string_t input(input_str);
72 return OP::template Operation<string_t, RESULT_TYPE>(input, result);
73 }
74};
75
76template <class OP>
77struct ToCStringCastWrapper {
78 template <class SOURCE_TYPE, class RESULT_TYPE>
79 static bool Operation(SOURCE_TYPE input, RESULT_TYPE &result) {
80 Vector result_vector(LogicalType::VARCHAR, nullptr);
81 auto result_string = OP::template Operation<SOURCE_TYPE>(input, result_vector);
82 auto result_size = result_string.GetSize();
83 auto result_data = result_string.GetData();
84
85 char *allocated_data = char_ptr_cast(duckdb_malloc(result_size + 1));
86 memcpy(allocated_data, result_data, result_size);
87 allocated_data[result_size] = '\0';
88 result.data = allocated_data;
89 result.size = result_size;
90 return true;
91 }
92};
93
94//===--------------------------------------------------------------------===//
95// Blob Casts
96//===--------------------------------------------------------------------===//
97struct FromCBlobCastWrapper {
98 template <class SOURCE_TYPE, class RESULT_TYPE>
99 static bool Operation(SOURCE_TYPE input_str, RESULT_TYPE &result) {
100 return false;
101 }
102};
103
104template <>
105bool FromCBlobCastWrapper::Operation(duckdb_blob input, duckdb_string &result);
106
107template <class SOURCE_TYPE, class RESULT_TYPE, class OP>
108RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) {
109 RESULT_TYPE result_value;
110 try {
111 if (!OP::template Operation<SOURCE_TYPE, RESULT_TYPE>(UnsafeFetch<SOURCE_TYPE>(result, col, row),
112 result_value)) {
113 return FetchDefaultValue::Operation<RESULT_TYPE>();
114 }
115 } catch (...) {
116 return FetchDefaultValue::Operation<RESULT_TYPE>();
117 }
118 return result_value;
119}
120
121} // namespace duckdb
122
123bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row);
124bool CanUseDeprecatedFetch(duckdb_result *result, idx_t col, idx_t row);
125