Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename extension to chsql #4

Merged
merged 6 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/MainDistributionPipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#
name: Main Extension Distribution Pipeline
on:
push:
release:
types: [published]
pull_request:
workflow_dispatch:

Expand All @@ -17,7 +18,7 @@ jobs:
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@main
with:
duckdb_version: v1.0.0
extension_name: dynamic_sql_clickhouse
extension_name: chsql

duckdb-stable-deploy:
name: Deploy extension binaries
Expand All @@ -26,6 +27,6 @@ jobs:
secrets: inherit
with:
duckdb_version: v1.0.0
extension_name: dynamic_sql_clickhouse
extension_name: chsql
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' }}
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 3.5)

# Set extension name here
set(TARGET_NAME dynamic_sql_clickhouse)
set(TARGET_NAME chsql)

# 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/dynamic_sql_clickhouse_extension.cpp src/default_table_functions.cpp)
set(EXTENSION_SOURCES src/chsql_extension.cpp src/default_table_functions.cpp)

build_static_extension(${TARGET_NAME} ${EXTENSION_SOURCES})
build_loadable_extension(${TARGET_NAME} " " ${EXTENSION_SOURCES})
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PROJ_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

# Configuration of extension
EXT_NAME=dynamic_sql_clickhouse
EXT_NAME=chsql
EXT_CONFIG=${PROJ_DIR}extension_config.cmake

# Include the Makefile from extension-ci-tools
Expand Down
47 changes: 47 additions & 0 deletions aliases.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
-- Type conversion macros
CREATE OR REPLACE MACRO toString(expr) AS CAST(expr AS VARCHAR);
CREATE OR REPLACE MACRO toInt8(expr) AS CAST(expr AS INT8);
CREATE OR REPLACE MACRO toInt16(expr) AS CAST(expr AS INT16);
CREATE OR REPLACE MACRO toInt32(expr) AS CAST(expr AS INT32);
CREATE OR REPLACE MACRO toInt64(expr) AS CAST(expr AS INT64);
CREATE OR REPLACE MACRO toInt128(expr) AS CAST(expr AS INT128);
CREATE OR REPLACE MACRO toInt256(expr) AS CAST(expr AS HUGEINT);
-- Type conversion with default values
CREATE OR REPLACE MACRO toInt8OrZero(expr) AS COALESCE(TRY_CAST(expr AS INT8), 0);
CREATE OR REPLACE MACRO toInt16OrZero(expr) AS COALESCE(TRY_CAST(expr AS INT16), 0);
CREATE OR REPLACE MACRO toInt32OrZero(expr) AS COALESCE(TRY_CAST(expr AS INT32), 0);
CREATE OR REPLACE MACRO toInt64OrZero(expr) AS COALESCE(TRY_CAST(expr AS INT64), 0);
CREATE OR REPLACE MACRO toInt128OrZero(expr) AS COALESCE(TRY_CAST(expr AS INT128), 0);
CREATE OR REPLACE MACRO toInt256OrZero(expr) AS COALESCE(TRY_CAST(expr AS HUGEINT), 0);
CREATE OR REPLACE MACRO toInt8OrNull(expr) AS TRY_CAST(expr AS INT8);
CREATE OR REPLACE MACRO toInt16OrNull(expr) AS TRY_CAST(expr AS INT16);
CREATE OR REPLACE MACRO toInt32OrNull(expr) AS TRY_CAST(expr AS INT32);
CREATE OR REPLACE MACRO toInt64OrNull(expr) AS TRY_CAST(expr AS INT64);
CREATE OR REPLACE MACRO toInt128OrNull(expr) AS TRY_CAST(expr AS INT128);
CREATE OR REPLACE MACRO toInt256OrNull(expr) AS TRY_CAST(expr AS HUGEINT);
-- Unsigned integer conversion macros
CREATE OR REPLACE MACRO toUInt8(expr) AS CAST(expr AS UTINYINT);
CREATE OR REPLACE MACRO toUInt16(expr) AS CAST(expr AS USMALLINT);
CREATE OR REPLACE MACRO toUInt32(expr) AS CAST(expr AS UINTEGER);
CREATE OR REPLACE MACRO toUInt64(expr) AS CAST(expr AS UBIGINT);
-- Unsigned integer conversion with default values
CREATE OR REPLACE MACRO toUInt8OrZero(expr) AS COALESCE(TRY_CAST(expr AS UTINYINT), 0);
CREATE OR REPLACE MACRO toUInt16OrZero(expr) AS COALESCE(TRY_CAST(expr AS USMALLINT), 0);
CREATE OR REPLACE MACRO toUInt32OrZero(expr) AS COALESCE(TRY_CAST(expr AS UINTEGER), 0);
CREATE OR REPLACE MACRO toUInt64OrZero(expr) AS COALESCE(TRY_CAST(expr AS UBIGINT), 0);
CREATE OR REPLACE MACRO toUInt8OrNull(expr) AS TRY_CAST(expr AS UTINYINT);
CREATE OR REPLACE MACRO toUInt16OrNull(expr) AS TRY_CAST(expr AS USMALLINT);
CREATE OR REPLACE MACRO toUInt32OrNull(expr) AS TRY_CAST(expr AS UINTEGER);
CREATE OR REPLACE MACRO toUInt64OrNull(expr) AS TRY_CAST(expr AS UBIGINT);
-- Floating-point conversion macros
CREATE OR REPLACE MACRO toFloat(expr) AS CAST(expr AS DOUBLE);
CREATE OR REPLACE MACRO toFloatOrNull(expr) AS TRY_CAST(expr AS DOUBLE);
CREATE OR REPLACE MACRO toFloatOrZero(expr) AS COALESCE(TRY_CAST(expr AS DOUBLE), 0);
-- Arithmetic macros
CREATE OR REPLACE MACRO intDiv(a, b) AS (a / b);
CREATE OR REPLACE MACRO intDivOrZero(a, b) AS COALESCE((a / b), 0);
-- String matching macro
CREATE OR REPLACE MACRO match(string, token) AS (string LIKE token);
-- Array macros
CREATE OR REPLACE MACRO arrayExists(needle, haystack) AS (haystack @> ARRAY[needle]);
CREATE OR REPLACE MACRO arrayMap(e, arr) AS (array_transform(arr, e -> (e * e)));
20 changes: 20 additions & 0 deletions description.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
extension:
name: chsql
description: Clickhouse SQL Macros for DuckDB
version: 1.0.0
language: C++
build: cmake
license: MIT
maintainers:
- lmangani

repo:
github: lmangani/duckdb-extension-clickhouse-sql
ref: e3024a76df741864696010130f72c79cbad2274d

docs:
hello_world: |
SELECT toString('world') as hello;
extended_description: |
This extension provides a growing number of Clickhouse SQL Macros for DuckDB.

2 changes: 1 addition & 1 deletion extension_config.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is included by DuckDB's build system. It specifies which extension to load

# Extension from this repo
duckdb_extension_load(dynamic_sql_clickhouse
duckdb_extension_load(chsql
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}
LOAD_TESTS
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define DUCKDB_EXTENSION_MAIN

#include "dynamic_sql_clickhouse_extension.hpp"
#include "chsql_extension.hpp"
#include "duckdb.hpp"
#include "duckdb/common/exception.hpp"
#include "duckdb/common/string_util.hpp"
Expand Down Expand Up @@ -28,8 +28,9 @@ namespace duckdb {
// Add the text of your SQL macro as a raw string with the format R"( select 42 )"


static DefaultMacro dynamic_sql_clickhouse_macros[] = {
static DefaultMacro chsql_macros[] = {
{DEFAULT_SCHEMA, "times_two", {"x", nullptr}, R"(x*2)"},
// -- Type conversion macros
{DEFAULT_SCHEMA, "toString", {"x", nullptr}, R"(CAST(x AS VARCHAR))"},
{DEFAULT_SCHEMA, "toInt8", {"x", nullptr}, R"(CAST(x AS INT8))"},
{DEFAULT_SCHEMA, "toInt16", {"x", nullptr}, R"(CAST(x AS INT16))"},
Expand All @@ -49,6 +50,7 @@ static DefaultMacro dynamic_sql_clickhouse_macros[] = {
{DEFAULT_SCHEMA, "toInt64OrNull", {"x", nullptr}, R"(TRY_CAST(x AS INT64))"},
{DEFAULT_SCHEMA, "toInt128OrNull", {"x", nullptr}, R"(TRY_CAST(x AS INT128))"},
{DEFAULT_SCHEMA, "toInt256OrNull", {"x", nullptr}, R"(TRY_CAST(x AS HUGEINT))"},
// -- Unsigned integer conversion macros
{DEFAULT_SCHEMA, "toUInt8", {"x", nullptr}, R"(CAST(x AS UTINYINT))"},
{DEFAULT_SCHEMA, "toUInt16", {"x", nullptr}, R"(CAST(x AS USMALLINT))"},
{DEFAULT_SCHEMA, "toUInt32", {"x", nullptr}, R"(CAST(x AS UINTEGER))"},
Expand All @@ -61,16 +63,22 @@ static DefaultMacro dynamic_sql_clickhouse_macros[] = {
{DEFAULT_SCHEMA, "toUInt16OrNull", {"x", nullptr}, R"(TRY_CAST(x AS USMALLINT))"}, // And here
{DEFAULT_SCHEMA, "toUInt32OrNull", {"x", nullptr}, R"(TRY_CAST(x AS UINTEGER))"}, // Also here
{DEFAULT_SCHEMA, "toUInt64OrNull", {"x", nullptr}, R"(TRY_CAST(x AS UBIGINT))"}, // And here
// -- Floating-point conversion macros
{DEFAULT_SCHEMA, "toFloat", {"x", nullptr}, R"(CAST(x AS DOUBLE))"},
{DEFAULT_SCHEMA, "toFloatOrNull", {"x", nullptr}, R"(TRY_CAST(x AS DOUBLE))"},
{DEFAULT_SCHEMA, "toFloatOrZero", {"x", nullptr}, R"(CASE WHEN TRY_CAST(x AS DOUBLE) IS NOT NULL THEN CAST(x AS DOUBLE) ELSE 0 END)"},
// -- Arithmetic macros
{DEFAULT_SCHEMA, "intDiv", {"a", "b"}, R"((CAST(a AS BIGINT) / CAST(b AS BIGINT)))"},
// -- String matching macros
{DEFAULT_SCHEMA, "match", {"string", "token"}, R"(string LIKE token)"},
// -- Array macros
{DEFAULT_SCHEMA, "arrayExists", {"needle", "haystack"}, R"(haystack @> ARRAY[needle])"},
{DEFAULT_SCHEMA, "arrayMap", {"e", "arr"}, R"(array_transform(arr, e -> (e * e)))"},
{nullptr, nullptr, {nullptr}, nullptr}};

// To add a new table SQL macro, add a new macro to this array!
// Copy and paste the top item in the array into the
// second-to-last position and make some modifications.
// Copy and paste the top item in the array into the
// second-to-last position and make some modifications.
// (essentially, leave the last entry in the array as {nullptr, nullptr, {nullptr}, nullptr})

// Keep the DEFAULT_SCHEMA (no change needed)
Expand All @@ -80,67 +88,67 @@ static DefaultMacro dynamic_sql_clickhouse_macros[] = {
// If your function has parameters with default values, add their names and values in quotes inside of {}'s inside of the {}.
// Be sure to keep {nullptr, nullptr} at the end
// If you do not have parameters with default values, simplify to {nullptr, nullptr}
// Add the text of your SQL macro as a raw string with the format R"( select 42; )"
// Add the text of your SQL macro as a raw string with the format R"( select 42; )"

// clang-format off
static const DefaultTableMacro dynamic_sql_clickhouse_table_macros[] = {
static const DefaultTableMacro chsql_table_macros[] = {
{DEFAULT_SCHEMA, "times_two_table", {"x", nullptr}, {{"two", "2"}, {nullptr, nullptr}}, R"(SELECT x * two as output_column;)"},
{nullptr, nullptr, {nullptr}, {{nullptr, nullptr}}, nullptr}
};
// clang-format on

inline void DynamicSqlClickhouseScalarFun(DataChunk &args, ExpressionState &state, Vector &result) {
inline void ChSqlScalarFun(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, "DynamicSqlClickhouse "+name.GetString()+" 🐥");;
return StringVector::AddString(result, "ChSql "+name.GetString()+" 🐥");;
});
}

inline void DynamicSqlClickhouseOpenSSLVersionScalarFun(DataChunk &args, ExpressionState &state, Vector &result) {
inline void ChSqlOpenSSLVersionScalarFun(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, "DynamicSqlClickhouse " + name.GetString() +
return StringVector::AddString(result, "ChSql " + name.GetString() +
", my linked OpenSSL version is " +
OPENSSL_VERSION_TEXT );;
});
}

static void LoadInternal(DatabaseInstance &instance) {
// Register a scalar function
auto dynamic_sql_clickhouse_scalar_function = ScalarFunction("dynamic_sql_clickhouse", {LogicalType::VARCHAR}, LogicalType::VARCHAR, DynamicSqlClickhouseScalarFun);
ExtensionUtil::RegisterFunction(instance, dynamic_sql_clickhouse_scalar_function);
auto chsql_scalar_function = ScalarFunction("chsql", {LogicalType::VARCHAR}, LogicalType::VARCHAR, ChSqlScalarFun);
ExtensionUtil::RegisterFunction(instance, chsql_scalar_function);

// Register another scalar function
auto dynamic_sql_clickhouse_openssl_version_scalar_function = ScalarFunction("dynamic_sql_clickhouse_openssl_version", {LogicalType::VARCHAR},
LogicalType::VARCHAR, DynamicSqlClickhouseOpenSSLVersionScalarFun);
ExtensionUtil::RegisterFunction(instance, dynamic_sql_clickhouse_openssl_version_scalar_function);
auto chsql_openssl_version_scalar_function = ScalarFunction("chsql_openssl_version", {LogicalType::VARCHAR},
LogicalType::VARCHAR, ChSqlOpenSSLVersionScalarFun);
ExtensionUtil::RegisterFunction(instance, chsql_openssl_version_scalar_function);

// Macros
for (idx_t index = 0; dynamic_sql_clickhouse_macros[index].name != nullptr; index++) {
auto info = DefaultFunctionGenerator::CreateInternalMacroInfo(dynamic_sql_clickhouse_macros[index]);
for (idx_t index = 0; chsql_macros[index].name != nullptr; index++) {
auto info = DefaultFunctionGenerator::CreateInternalMacroInfo(chsql_macros[index]);
ExtensionUtil::RegisterFunction(instance, *info);
}
// Table Macros
for (idx_t index = 0; dynamic_sql_clickhouse_table_macros[index].name != nullptr; index++) {
auto table_info = DefaultTableFunctionGenerator::CreateTableMacroInfo(dynamic_sql_clickhouse_table_macros[index]);
for (idx_t index = 0; chsql_table_macros[index].name != nullptr; index++) {
auto table_info = DefaultTableFunctionGenerator::CreateTableMacroInfo(chsql_table_macros[index]);
ExtensionUtil::RegisterFunction(instance, *table_info);
}
}

void DynamicSqlClickhouseExtension::Load(DuckDB &db) {
void ChsqlExtension::Load(DuckDB &db) {
LoadInternal(*db.instance);
}
std::string DynamicSqlClickhouseExtension::Name() {
return "dynamic_sql_clickhouse";
std::string ChsqlExtension::Name() {
return "chsql";
}

std::string DynamicSqlClickhouseExtension::Version() const {
#ifdef EXT_VERSION_DYNAMIC_SQL_CLICKHOUSE
return EXT_VERSION_DYNAMIC_SQL_CLICKHOUSE;
std::string ChsqlExtension::Version() const {
#ifdef EXT_VERSION_CHSQL
return EXT_VERSION_CHSQL;
#else
return "";
#endif
Expand All @@ -150,12 +158,12 @@ std::string DynamicSqlClickhouseExtension::Version() const {

extern "C" {

DUCKDB_EXTENSION_API void dynamic_sql_clickhouse_init(duckdb::DatabaseInstance &db) {
DUCKDB_EXTENSION_API void chsql_init(duckdb::DatabaseInstance &db) {
duckdb::DuckDB db_wrapper(db);
db_wrapper.LoadExtension<duckdb::DynamicSqlClickhouseExtension>();
db_wrapper.LoadExtension<duckdb::ChsqlExtension>();
}

DUCKDB_EXTENSION_API const char *dynamic_sql_clickhouse_version() {
DUCKDB_EXTENSION_API const char *chsql_version() {
return duckdb::DuckDB::LibraryVersion();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace duckdb {

class DynamicSqlClickhouseExtension : public Extension {
class ChsqlExtension : public Extension {
public:
void Load(DuckDB &db) override;
std::string Name() override;
Expand Down
20 changes: 10 additions & 10 deletions test/sql/dynamic_sql_clickhouse.test → test/sql/chsql.test
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# name: test/sql/dynamic_sql_clickhouse.test
# description: test dynamic_sql_clickhouse extension
# group: [dynamic_sql_clickhouse]
# name: test/sql/chsql.test
# description: test chsql extension
# group: [chsql]

# Before we load the extension, this will fail
statement error
SELECT dynamic_sql_clickhouse('Sam');
SELECT chsql('Sam');
----
Catalog Error: Scalar Function with name dynamic_sql_clickhouse does not exist!
Catalog Error: Scalar Function with name chsql does not exist!

# Require statement will ensure this test is run with this extension loaded
require dynamic_sql_clickhouse
require chsql

# Confirm the extension works
query I
SELECT dynamic_sql_clickhouse('Works');
SELECT chsql('Works');
----
DynamicSqlClickhouse Works 🐥
ChSql Works 🐥

query I
SELECT dynamic_sql_clickhouse_openssl_version('Hello');
SELECT chsql_openssl_version('Hello');
----
<REGEX>:.*DynamicSqlClickhouse Hello, my linked OpenSSL version is OpenSSL.*
<REGEX>:.*ChSql Hello, my linked OpenSSL version is OpenSSL.*

query I
SELECT toString('123')
Expand Down
Loading