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

Backport #2 #3

Merged
merged 4 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
4 changes: 2 additions & 2 deletions .github/workflows/MainDistributionPipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
name: Build extension binaries
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@main
with:
duckdb_version: main
duckdb_version: v1.0.0
extension_name: dynamic_sql_clickhouse

duckdb-stable-deploy:
Expand All @@ -25,7 +25,7 @@ jobs:
uses: duckdb/extension-ci-tools/.github/workflows/_extension_deploy.yml@main
secrets: inherit
with:
duckdb_version: main
duckdb_version: v1.0.0
extension_name: dynamic_sql_clickhouse
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' }}
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
project(${TARGET_NAME})
include_directories(src/include)

set(EXTENSION_SOURCES src/dynamic_sql_clickhouse_extension.cpp)
set(EXTENSION_SOURCES src/dynamic_sql_clickhouse_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 duckdb
Submodule duckdb updated 1554 files
148 changes: 148 additions & 0 deletions src/default_table_functions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#include "default_table_functions.hpp"
#include "duckdb/catalog/catalog_entry/table_macro_catalog_entry.hpp"
#include "duckdb/parser/parser.hpp"
#include "duckdb/parser/parsed_data/create_macro_info.hpp"
#include "duckdb/parser/statement/select_statement.hpp"
#include "duckdb/function/table_macro_function.hpp"

namespace duckdb {

// clang-format off
static const DefaultTableMacro internal_table_macros[] = {
{DEFAULT_SCHEMA, "histogram_values", {"source", "col_name", nullptr}, {{"bin_count", "10"}, {"technique", "'auto'"}, {nullptr, nullptr}}, R"(
WITH bins AS (
SELECT
CASE
WHEN (NOT (can_cast_implicitly(MIN(col_name), NULL::BIGINT) OR
can_cast_implicitly(MIN(col_name), NULL::DOUBLE) OR
can_cast_implicitly(MIN(col_name), NULL::TIMESTAMP)) AND technique='auto')
OR technique='sample'
THEN
approx_top_k(col_name, bin_count)
WHEN technique='equi-height'
THEN
quantile(col_name, [x / bin_count::DOUBLE for x in generate_series(1, bin_count)])
WHEN technique='equi-width'
THEN
equi_width_bins(MIN(col_name), MAX(col_name), bin_count, false)
WHEN technique='equi-width-nice' OR technique='auto'
THEN
equi_width_bins(MIN(col_name), MAX(col_name), bin_count, true)
ELSE
error(concat('Unrecognized technique ', technique))
END AS bins
FROM query_table(source::VARCHAR)
)
SELECT UNNEST(map_keys(histogram)) AS bin, UNNEST(map_values(histogram)) AS count
FROM (
SELECT CASE
WHEN (NOT (can_cast_implicitly(MIN(col_name), NULL::BIGINT) OR
can_cast_implicitly(MIN(col_name), NULL::DOUBLE) OR
can_cast_implicitly(MIN(col_name), NULL::TIMESTAMP)) AND technique='auto')
OR technique='sample'
THEN
histogram_exact(col_name, bins)
ELSE
histogram(col_name, bins)
END AS histogram
FROM query_table(source::VARCHAR), bins
);
)"},
{DEFAULT_SCHEMA, "histogram", {"source", "col_name", nullptr}, {{"bin_count", "10"}, {"technique", "'auto'"}, {nullptr, nullptr}}, R"(
SELECT
CASE
WHEN is_histogram_other_bin(bin)
THEN '(other values)'
WHEN (NOT (can_cast_implicitly(bin, NULL::BIGINT) OR
can_cast_implicitly(bin, NULL::DOUBLE) OR
can_cast_implicitly(bin, NULL::TIMESTAMP)) AND technique='auto')
OR technique='sample'
THEN bin::VARCHAR
WHEN row_number() over () = 1
THEN concat('x <= ', bin::VARCHAR)
ELSE concat(lag(bin::VARCHAR) over (), ' < x <= ', bin::VARCHAR)
END AS bin,
count,
bar(count, 0, max(count) over ()) AS bar
FROM histogram_values(source, col_name, bin_count := bin_count, technique := technique);
)"},
{nullptr, nullptr, {nullptr}, {{nullptr, nullptr}}, nullptr}
};
// clang-format on

DefaultTableFunctionGenerator::DefaultTableFunctionGenerator(Catalog &catalog, SchemaCatalogEntry &schema)
: DefaultGenerator(catalog), schema(schema) {
}

unique_ptr<CreateMacroInfo>
DefaultTableFunctionGenerator::CreateInternalTableMacroInfo(const DefaultTableMacro &default_macro,
unique_ptr<MacroFunction> function) {
for (idx_t param_idx = 0; default_macro.parameters[param_idx] != nullptr; param_idx++) {
function->parameters.push_back(make_uniq<ColumnRefExpression>(default_macro.parameters[param_idx]));
}
for (idx_t named_idx = 0; default_macro.named_parameters[named_idx].name != nullptr; named_idx++) {
auto expr_list = Parser::ParseExpressionList(default_macro.named_parameters[named_idx].default_value);
if (expr_list.size() != 1) {
throw InternalException("Expected a single expression");
}
function->default_parameters.insert(
make_pair(default_macro.named_parameters[named_idx].name, std::move(expr_list[0])));
}

auto type = CatalogType::TABLE_MACRO_ENTRY;
auto bind_info = make_uniq<CreateMacroInfo>(type);
bind_info->schema = default_macro.schema;
bind_info->name = default_macro.name;
bind_info->temporary = true;
bind_info->internal = true;
bind_info->function = std::move(function);
return bind_info;
}

unique_ptr<CreateMacroInfo>
DefaultTableFunctionGenerator::CreateTableMacroInfo(const DefaultTableMacro &default_macro) {
Parser parser;
parser.ParseQuery(default_macro.macro);
if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) {
throw InternalException("Expected a single select statement in CreateTableMacroInfo internal");
}
auto node = std::move(parser.statements[0]->Cast<SelectStatement>().node);

auto result = make_uniq<TableMacroFunction>(std::move(node));
return CreateInternalTableMacroInfo(default_macro, std::move(result));
}

static unique_ptr<CreateFunctionInfo> GetDefaultTableFunction(const string &input_schema, const string &input_name) {
auto schema = StringUtil::Lower(input_schema);
auto name = StringUtil::Lower(input_name);
for (idx_t index = 0; internal_table_macros[index].name != nullptr; index++) {
if (internal_table_macros[index].schema == schema && internal_table_macros[index].name == name) {
return DefaultTableFunctionGenerator::CreateTableMacroInfo(internal_table_macros[index]);
}
}
return nullptr;
}

unique_ptr<CatalogEntry> DefaultTableFunctionGenerator::CreateDefaultEntry(ClientContext &context,
const string &entry_name) {
auto info = GetDefaultTableFunction(schema.name, entry_name);
if (info) {
return make_uniq_base<CatalogEntry, TableMacroCatalogEntry>(catalog, schema, info->Cast<CreateMacroInfo>());
}
return nullptr;
}

vector<string> DefaultTableFunctionGenerator::GetDefaultEntries() {
vector<string> result;
for (idx_t index = 0; internal_table_macros[index].name != nullptr; index++) {
if (StringUtil::Lower(internal_table_macros[index].name) != internal_table_macros[index].name) {
throw InternalException("Default macro name %s should be lowercase", internal_table_macros[index].name);
}
if (internal_table_macros[index].schema == schema.name) {
result.emplace_back(internal_table_macros[index].name);
}
}
return result;
}

} // namespace duckdb
4 changes: 2 additions & 2 deletions src/dynamic_sql_clickhouse_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
// OpenSSL linked through vcpkg
#include <openssl/opensslv.h>

#include "duckdb/catalog/default/default_functions.hpp"
#include "duckdb/catalog/default/default_table_functions.hpp"
#include "default_functions.hpp"
#include "default_table_functions.hpp"

namespace duckdb {

Expand Down
41 changes: 41 additions & 0 deletions src/include/default_functions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
// DuckDB
//
// duckdb/catalog/default/default_functions.hpp
//
//
//===----------------------------------------------------------------------===//

#pragma once

#include "duckdb/catalog/default/default_generator.hpp"
#include "duckdb/parser/parsed_data/create_macro_info.hpp"

namespace duckdb {
class SchemaCatalogEntry;

struct DefaultMacro {
const char *schema;
const char *name;
const char *parameters[8];
const char *macro;
};

class DefaultFunctionGenerator : public DefaultGenerator {
public:
DefaultFunctionGenerator(Catalog &catalog, SchemaCatalogEntry &schema);

SchemaCatalogEntry &schema;

DUCKDB_API static unique_ptr<CreateMacroInfo> CreateInternalMacroInfo(const DefaultMacro &default_macro);

public:
unique_ptr<CatalogEntry> CreateDefaultEntry(ClientContext &context, const string &entry_name) override;
vector<string> GetDefaultEntries() override;

private:
static unique_ptr<CreateMacroInfo> CreateInternalMacroInfo(const DefaultMacro &default_macro,
unique_ptr<MacroFunction> function);
};

} // namespace duckdb
47 changes: 47 additions & 0 deletions src/include/default_table_functions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===----------------------------------------------------------------------===//
// DuckDB
//
// duckdb/catalog/default/default_table_functions.hpp
//
//
//===----------------------------------------------------------------------===//

#pragma once

#include "duckdb/catalog/default/default_generator.hpp"
#include "duckdb/parser/parsed_data/create_macro_info.hpp"

namespace duckdb {
class SchemaCatalogEntry;

struct DefaultNamedParameter {
const char *name;
const char *default_value;
};

struct DefaultTableMacro {
const char *schema;
const char *name;
const char *parameters[8];
DefaultNamedParameter named_parameters[8];
const char *macro;
};

class DefaultTableFunctionGenerator : public DefaultGenerator {
public:
DefaultTableFunctionGenerator(Catalog &catalog, SchemaCatalogEntry &schema);

SchemaCatalogEntry &schema;

public:
unique_ptr<CatalogEntry> CreateDefaultEntry(ClientContext &context, const string &entry_name) override;
vector<string> GetDefaultEntries() override;

static unique_ptr<CreateMacroInfo> CreateTableMacroInfo(const DefaultTableMacro &default_macro);

private:
static unique_ptr<CreateMacroInfo> CreateInternalTableMacroInfo(const DefaultTableMacro &default_macro,
unique_ptr<MacroFunction> function);
};

} // namespace duckdb
Loading