@@ -125,6 +125,25 @@ static std::string GetHttpErrorMessage(const duckdb_httplib_openssl::Result &res
125125 return err_message;
126126}
127127
128+ // Helper function to convert list of entries to a map of parameters.
129+ template <class T >
130+ static int ConvertListEntryToMap (const list_entry_t & list_entry, const duckdb::Vector& input, T& result) {
131+ for (idx_t i = list_entry.offset ; i < list_entry.offset + list_entry.length ; i++) {
132+ const auto &child_value = input.GetValue (i);
133+
134+ Vector tmp (child_value);
135+ auto &children = StructVector::GetEntries (tmp);
136+
137+ if (children.size () == 2 ) {
138+ auto name = FlatVector::GetData<string_t >(*children[0 ]);
139+ auto data = FlatVector::GetData<string_t >(*children[1 ]);
140+ std::string key = name->GetString ();
141+ std::string val = data->GetString ();
142+ result.emplace (key, val);
143+ }
144+ }
145+ return result.size ();
146+ }
128147
129148static void HTTPGetRequestFunction (DataChunk &args, ExpressionState &state, Vector &result) {
130149 D_ASSERT (args.data .size () == 1 );
@@ -149,6 +168,50 @@ static void HTTPGetRequestFunction(DataChunk &args, ExpressionState &state, Vect
149168 });
150169}
151170
171+ static void HTTPGetExRequestFunction (DataChunk &args, ExpressionState &state, Vector &result) {
172+ D_ASSERT (args.data .size () == 3 );
173+
174+ using STRING_TYPE = PrimitiveType<string_t >;
175+ using LENTRY_TYPE = PrimitiveType<list_entry_t >;
176+
177+ auto &url_vector = args.data [0 ];
178+ auto &headers_vector = args.data [1 ];
179+ auto &headers_entry = ListVector::GetEntry (headers_vector);
180+ auto ¶ms_vector = args.data [2 ];
181+ auto ¶ms_entry = ListVector::GetEntry (params_vector);
182+
183+ GenericExecutor::ExecuteTernary<STRING_TYPE, LENTRY_TYPE, LENTRY_TYPE, STRING_TYPE>(
184+ url_vector, headers_vector, params_vector, result, args.size (),
185+ [&](STRING_TYPE url, LENTRY_TYPE headers, LENTRY_TYPE params) {
186+ std::string url_str = url.val .GetString ();
187+
188+ // Use helper to setup client and parse URL
189+ auto client_and_path = SetupHttpClient (url_str);
190+ auto &client = client_and_path.first ;
191+ auto &path = client_and_path.second ;
192+
193+ // Prepare headers
194+ duckdb_httplib_openssl::Headers header_map;
195+ auto header_list = headers.val ;
196+ ConvertListEntryToMap<duckdb_httplib_openssl::Headers>(header_list, headers_entry, header_map);
197+
198+ // Prepare params
199+ duckdb_httplib_openssl::Params param_map;
200+ auto params_list = params.val ;
201+ ConvertListEntryToMap<duckdb_httplib_openssl::Params>(params_list, params_entry, param_map);
202+
203+ // Make the POST request with headers and params
204+ auto res = client.Get (path.c_str (), param_map, header_map);
205+ if (res) {
206+ std::string response = GetJsonResponse (res->status , res->reason , res->body );
207+ return StringVector::AddString (result, response);
208+ } else {
209+ std::string response = GetJsonResponse (-1 , GetHttpErrorMessage (res, " GET" ), " " );
210+ return StringVector::AddString (result, response);
211+ }
212+ });
213+ }
214+
152215static void HTTPPostRequestFunction (DataChunk &args, ExpressionState &state, Vector &result) {
153216 D_ASSERT (args.data .size () == 3 );
154217
@@ -173,20 +236,7 @@ static void HTTPPostRequestFunction(DataChunk &args, ExpressionState &state, Vec
173236 // Prepare headers
174237 duckdb_httplib_openssl::Headers header_map;
175238 auto header_list = headers.val ;
176- for (idx_t i = header_list.offset ; i < header_list.offset + header_list.length ; i++) {
177- const auto &child_value = headers_entry.GetValue (i);
178-
179- Vector tmp (child_value);
180- auto &children = StructVector::GetEntries (tmp);
181-
182- if (children.size () == 2 ) {
183- auto name = FlatVector::GetData<string_t >(*children[0 ]);
184- auto data = FlatVector::GetData<string_t >(*children[1 ]);
185- std::string key = name->GetString ();
186- std::string val = data->GetString ();
187- header_map.emplace (key, val);
188- }
189- }
239+ ConvertListEntryToMap<duckdb_httplib_openssl::Headers>(header_list, headers_entry, header_map);
190240
191241 // Make the POST request with headers and body
192242 auto res = client.Post (path.c_str (), header_map, body.val .GetString (), " application/json" );
@@ -204,6 +254,10 @@ static void HTTPPostRequestFunction(DataChunk &args, ExpressionState &state, Vec
204254static void LoadInternal (DatabaseInstance &instance) {
205255 ScalarFunctionSet http_get (" http_get" );
206256 http_get.AddFunction (ScalarFunction ({LogicalType::VARCHAR}, LogicalType::JSON (), HTTPGetRequestFunction));
257+ http_get.AddFunction (ScalarFunction (
258+ {LogicalType::VARCHAR, LogicalType::MAP (LogicalType::VARCHAR, LogicalType::VARCHAR),
259+ LogicalType::MAP (LogicalType::VARCHAR, LogicalType::VARCHAR)},
260+ LogicalType::JSON (), HTTPGetExRequestFunction));
207261 ExtensionUtil::RegisterFunction (instance, http_get);
208262
209263 ScalarFunctionSet http_post (" http_post" );
0 commit comments