diff --git a/src/quack_extension.cpp b/src/quack_extension.cpp index 468b2e2..adf6bbd 100644 --- a/src/quack_extension.cpp +++ b/src/quack_extension.cpp @@ -7,6 +7,8 @@ #include "duckdb/function/scalar_function.hpp" #include "duckdb/main/extension_util.hpp" #include +#include "duckdb/catalog/default/default_functions.hpp" +#include "duckdb/catalog/default/default_table_functions.hpp" // OpenSSL linked through vcpkg #include @@ -33,7 +35,22 @@ inline void QuackOpenSSLVersionScalarFun(DataChunk &args, ExpressionState &state }); } +// clang-format off +// SQL scalar macros +static DefaultMacro quack_macros[] = { + {DEFAULT_SCHEMA, "default_to_times_two", {"x", nullptr}, {{"multiplier", "2"}, {nullptr, nullptr}}, R"( x * multiplier )"}, + {nullptr, nullptr, {nullptr}, {{nullptr, nullptr}}, nullptr} +}; + +// SQL table macros +static const DefaultTableMacro quack_table_macros[] = { + {DEFAULT_SCHEMA, "default_to_times_two_table", {"x", nullptr}, {{"multiplier", "2"}, {nullptr, nullptr}}, R"( SELECT x * multiplier as output_column; )"}, + {nullptr, nullptr, {nullptr}, {{nullptr, nullptr}}, nullptr} +}; +// clang-format on + static void LoadInternal(DatabaseInstance &instance) { + // Register a scalar function auto quack_scalar_function = ScalarFunction("quack", {LogicalType::VARCHAR}, LogicalType::VARCHAR, QuackScalarFun); ExtensionUtil::RegisterFunction(instance, quack_scalar_function); @@ -42,6 +59,17 @@ static void LoadInternal(DatabaseInstance &instance) { auto quack_openssl_version_scalar_function = ScalarFunction("quack_openssl_version", {LogicalType::VARCHAR}, LogicalType::VARCHAR, QuackOpenSSLVersionScalarFun); ExtensionUtil::RegisterFunction(instance, quack_openssl_version_scalar_function); + + // Register SQL scalar macros + for (idx_t index = 0; quack_macros[index].name != nullptr; index++) { + auto info = DefaultFunctionGenerator::CreateInternalMacroInfo(quack_macros[index]); + ExtensionUtil::RegisterFunction(instance, *info); + } + // Register SQL table macros + for (idx_t index = 0; quack_table_macros[index].name != nullptr; index++) { + auto table_info = DefaultTableFunctionGenerator::CreateTableMacroInfo(quack_table_macros[index]); + ExtensionUtil::RegisterFunction(instance, *table_info); + } } void QuackExtension::Load(DuckDB &db) { diff --git a/test/sql/quack.test b/test/sql/quack.test index 519a354..b88c533 100644 --- a/test/sql/quack.test +++ b/test/sql/quack.test @@ -12,12 +12,27 @@ Catalog Error: Scalar Function with name quack does not exist! require quack # Confirm the extension works + +# Test scalar C++ function query I SELECT quack('Sam'); ---- Quack Sam 🐥 +# Test scalar C++ function using vcpkg and openssl query I SELECT quack_openssl_version('Michael') ILIKE 'Quack Michael, my linked OpenSSL version is OpenSSL%'; ---- true + +# Test scalar macro overriding the default +query I +SELECT default_to_times_two(4, multiplier:=3); +---- +12 + +# Test table macro overriding the default +query I +SELECT * FROM default_to_times_two_table(5, multiplier:=3); +---- +15 \ No newline at end of file