Skip to content

Commit

Permalink
initial commit - it works.
Browse files Browse the repository at this point in the history
  • Loading branch information
mgdenno committed Dec 15, 2023
1 parent f772366 commit 5c49164
Show file tree
Hide file tree
Showing 15 changed files with 233 additions and 335 deletions.
177 changes: 0 additions & 177 deletions .github/workflows/ExtensionTemplate.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/MainDistributionPipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
with:
vcpkg_commit: a42af01b72c28a8e1d7b48107b33e4f286a55ef6
duckdb_version: v0.9.2
extension_name: quack
extension_name: hydro_duck

duckdb-stable-deploy:
name: Deploy extension binaries
Expand All @@ -27,6 +27,6 @@ jobs:
secrets: inherit
with:
duckdb_version: v0.9.2
extension_name: quack
extension_name: hydro_duck
deploy_latest: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' }}
deploy_versioned: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' }}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"C_Cpp.default.compilerPath": "/usr/bin/g++"
}
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.8.12)

# Set extension name here
set(TARGET_NAME quack)
set(TARGET_NAME hydro_duck)

# DuckDB's extension distribution supports vcpkg. As such, dependencies can be added in ./vcpkg.json and then
# used in cmake with find_package. Feel free to remove or replace with other dependencies.
Expand All @@ -14,7 +14,7 @@ set(LOADABLE_EXTENSION_NAME ${TARGET_NAME}_loadable_extension)
project(${TARGET_NAME})
include_directories(src/include)

set(EXTENSION_SOURCES src/quack_extension.cpp)
set(EXTENSION_SOURCES src/hydro_duck_extension.cpp)

build_static_extension(${TARGET_NAME} ${EXTENSION_SOURCES})
build_loadable_extension(${TARGET_NAME} " " ${EXTENSION_SOURCES})
Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ ifeq ($(GEN),ninja)
GENERATOR=-G "Ninja" -DFORCE_COLORED_OUTPUT=1
endif

EXT_NAME=quack
EXT_NAME=hydro_duck

#### Configuration for this extension
EXTENSION_NAME=QUACK
EXTENSION_NAME=HYDRO_DUCK
EXTENSION_FLAGS=\
-DDUCKDB_EXTENSION_NAMES="quack" \
-DDUCKDB_EXTENSION_NAMES="hydro_duck" \
-DDUCKDB_EXTENSION_${EXTENSION_NAME}_PATH="$(PROJ_DIR)" \
-DDUCKDB_EXTENSION_${EXTENSION_NAME}_LOAD_TESTS=1 \
-DDUCKDB_EXTENSION_${EXTENSION_NAME}_INCLUDE_PATH="$(PROJ_DIR)src/include" \
Expand All @@ -49,7 +49,7 @@ BUILD_FLAGS=-DEXTENSION_STATIC_BUILD=1 $(EXTENSION_FLAGS) ${EXTRA_EXTENSIONS_FLA
CLIENT_FLAGS:=

#### Main build
# For regular CLI build, we link the quack extension directly into the DuckDB executable
# For regular CLI build, we link the hydro_duck extension directly into the DuckDB executable
CLIENT_FLAGS=-DDUCKDB_EXTENSION_${EXTENSION_NAME}_SHOULD_LINK=1

debug:
Expand Down Expand Up @@ -83,8 +83,8 @@ test_debug: debug
./build/debug/$(TEST_PATH) "$(PROJ_DIR)test/*"

#### Client tests
DEBUG_EXT_PATH='$(PROJ_DIR)build/debug/extension/quack/quack.duckdb_extension'
RELEASE_EXT_PATH='$(PROJ_DIR)build/release/extension/quack/quack.duckdb_extension'
DEBUG_EXT_PATH='$(PROJ_DIR)build/debug/extension/hydro_duck/hydro_duck.duckdb_extension'
RELEASE_EXT_PATH='$(PROJ_DIR)build/release/extension/hydro_duck/hydro_duck.duckdb_extension'
test_js: test_debug_js
test_debug_js: debug_js
cd duckdb/tools/nodejs && ${EXTENSION_NAME}_EXTENSION_BINARY_PATH=$(DEBUG_EXT_PATH) npm run test-path -- "../../../test/nodejs/**/*.js"
Expand Down
86 changes: 86 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Quack

This repository is based on https://github.com/duckdb/extension-template, check it out if you want to build and ship your own DuckDB extension.

---

This extension, Quack, allow you to ... <extension_goal>.


## Building
### Managing dependencies
DuckDB extensions uses VCPKG for dependency management. Enabling VCPKG is very simple: follow the [installation instructions](https://vcpkg.io/en/getting-started) or just run the following:
```shell
git clone https://github.com/Microsoft/vcpkg.git
./vcpkg/bootstrap-vcpkg.sh
export VCPKG_TOOLCHAIN_PATH=`pwd`/vcpkg/scripts/buildsystems/vcpkg.cmake
```
Note: VCPKG is only required for extensions that want to rely on it for dependency management. If you want to develop an extension without dependencies, or want to do your own dependency management, just skip this step. Note that the example extension uses VCPKG to build with a dependency for instructive purposes, so when skipping this step the build may not work without removing the dependency.

### Build steps
Now to build the extension, run:
```sh
make
```
The main binaries that will be built are:
```sh
./build/release/duckdb
./build/release/test/unittest
./build/release/extension/hydro_duck/hydro_duck.duckdb_extension
```
- `duckdb` is the binary for the duckdb shell with the extension code automatically loaded.
- `unittest` is the test runner of duckdb. Again, the extension is already linked into the binary.
- `hydro_duck.duckdb_extension` is the loadable binary as it would be distributed.

## Running the extension
To run the extension code, simply start the shell with `./build/release/duckdb`.

Now we can use the features from the extension directly in DuckDB. The template contains a single scalar function `hydro_duck()` that takes a string arguments and returns a string:
```
D select hydro_duck('Jane') as result;
┌───────────────┐
│ result │
│ varchar │
├───────────────┤
│ Quack Jane 🐥 │
└───────────────┘
```

## Running the tests
Different tests can be created for DuckDB extensions. The primary way of testing DuckDB extensions should be the SQL tests in `./test/sql`. These SQL tests can be run using:
```sh
make test
```

### Installing the deployed binaries
To install your extension binaries from S3, you will need to do two things. Firstly, DuckDB should be launched with the
`allow_unsigned_extensions` option set to true. How to set this will depend on the client you're using. Some examples:

CLI:
```shell
duckdb -unsigned
```

Python:
```python
con = duckdb.connect(':memory:', config={'allow_unsigned_extensions' : 'true'})
```

NodeJS:
```js
db = new duckdb.Database(':memory:', {"allow_unsigned_extensions": "true"});
```

Secondly, you will need to set the repository endpoint in DuckDB to the HTTP url of your bucket + version of the extension
you want to install. To do this run the following SQL query in DuckDB:
```sql
SET custom_extension_repository='bucket.s3.eu-west-1.amazonaws.com/<your_extension_name>/latest';
```
Note that the `/latest` path will allow you to install the latest extension version available for your current version of
DuckDB. To specify a specific version, you can pass the version instead.

After running these steps, you can install and load your extension using the regular INSTALL/LOAD commands in DuckDB:
```sql
INSTALL hydro_duck
LOAD hydro_duck
```
56 changes: 56 additions & 0 deletions src/hydro_duck_extension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#define DUCKDB_EXTENSION_MAIN

#include "hydro_duck_extension.hpp"
#include "duckdb.hpp"
#include "duckdb/common/exception.hpp"
#include "duckdb/common/string_util.hpp"
#include "duckdb/function/scalar_function.hpp"
#include "duckdb/function/aggregate_function.hpp"
#include "duckdb/main/extension_util.hpp"
#include <duckdb/parser/parsed_data/create_scalar_function_info.hpp>

#include "duckdb/function/aggregate_function.hpp"
#include "duckdb/function/function.hpp"


namespace duckdb {

inline void HydroDuckScalarFun(DataChunk &args, ExpressionState &state, Vector &result) {
auto &name_vector = args.data[0];
UnaryExecutor::Execute<string_t, string_t>(
name_vector, result, args.size(),
[&](string_t name) {
return StringVector::AddString(result, "HydroDuck "+name.GetString()+" 🐥");;
});
}

static void LoadInternal(DatabaseInstance &instance) {
// Register a scalar function
auto hydro_duck_scalar_function = ScalarFunction("quack", {LogicalType::VARCHAR}, LogicalType::VARCHAR, HydroDuckScalarFun);
ExtensionUtil::RegisterFunction(instance, hydro_duck_scalar_function);
}

void HydroDuckExtension::Load(DuckDB &db) {
LoadInternal(*db.instance);
}
std::string HydroDuckExtension::Name() {
return "hydro_duck";
}

} // namespace duckdb

extern "C" {

DUCKDB_EXTENSION_API void hydro_duck_init(duckdb::DatabaseInstance &db) {
duckdb::DuckDB db_wrapper(db);
db_wrapper.LoadExtension<duckdb::HydroDuckExtension>();
}

DUCKDB_EXTENSION_API const char *hydro_duck_version() {
return duckdb::DuckDB::LibraryVersion();
}
}

#ifndef DUCKDB_EXTENSION_MAIN
#error DUCKDB_EXTENSION_MAIN not defined
#endif
Loading

0 comments on commit 5c49164

Please sign in to comment.