duckdb 0.3.2-dev782.0 → 0.3.2-dev838.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +328 -22
- package/src/duckdb.hpp +30 -12
- package/src/parquet-amalgamation.cpp +33031 -31886
- package/src/parquet-amalgamation.hpp +58 -68
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -38204,6 +38204,9 @@ LogicalType LogicalType::STRUCT(child_list_t<LogicalType> children) {
|
|
|
38204
38204
|
return LogicalType(LogicalTypeId::STRUCT, move(info));
|
|
38205
38205
|
}
|
|
38206
38206
|
|
|
38207
|
+
//===--------------------------------------------------------------------===//
|
|
38208
|
+
// Map Type
|
|
38209
|
+
//===--------------------------------------------------------------------===//
|
|
38207
38210
|
LogicalType LogicalType::MAP(child_list_t<LogicalType> children) {
|
|
38208
38211
|
auto info = make_shared<StructTypeInfo>(move(children));
|
|
38209
38212
|
return LogicalType(LogicalTypeId::MAP, move(info));
|
|
@@ -38216,6 +38219,16 @@ LogicalType LogicalType::MAP(LogicalType key, LogicalType value) {
|
|
|
38216
38219
|
return LogicalType::MAP(move(child_types));
|
|
38217
38220
|
}
|
|
38218
38221
|
|
|
38222
|
+
const LogicalType &MapType::KeyType(const LogicalType &type) {
|
|
38223
|
+
D_ASSERT(type.id() == LogicalTypeId::MAP);
|
|
38224
|
+
return StructType::GetChildTypes(type)[0].second;
|
|
38225
|
+
}
|
|
38226
|
+
|
|
38227
|
+
const LogicalType &MapType::ValueType(const LogicalType &type) {
|
|
38228
|
+
D_ASSERT(type.id() == LogicalTypeId::MAP);
|
|
38229
|
+
return StructType::GetChildTypes(type)[1].second;
|
|
38230
|
+
}
|
|
38231
|
+
|
|
38219
38232
|
//===--------------------------------------------------------------------===//
|
|
38220
38233
|
// User Type
|
|
38221
38234
|
//===--------------------------------------------------------------------===//
|
|
@@ -74467,7 +74480,8 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry ¯o_func, FunctionE
|
|
|
74467
74480
|
} else if (defaults.find(arg->alias) != defaults.end()) {
|
|
74468
74481
|
return StringUtil::Format("Duplicate default parameters %s!", arg->alias);
|
|
74469
74482
|
}
|
|
74470
|
-
|
|
74483
|
+
auto alias = arg->alias;
|
|
74484
|
+
defaults[alias] = move(arg);
|
|
74471
74485
|
} else if (!defaults.empty()) {
|
|
74472
74486
|
return "Positional parameters cannot come after parameters with a default value!";
|
|
74473
74487
|
} else {
|
|
@@ -88573,9 +88587,9 @@ static void GenerateUUIDFunction(DataChunk &args, ExpressionState &state, Vector
|
|
|
88573
88587
|
}
|
|
88574
88588
|
|
|
88575
88589
|
void UUIDFun::RegisterFunction(BuiltinFunctions &set) {
|
|
88590
|
+
ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind);
|
|
88576
88591
|
// generate a random uuid
|
|
88577
|
-
set.AddFunction(
|
|
88578
|
-
ScalarFunction("gen_random_uuid", {}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind));
|
|
88592
|
+
set.AddFunction({"uuid", "gen_random_uuid"}, uuid_function);
|
|
88579
88593
|
}
|
|
88580
88594
|
|
|
88581
88595
|
} // namespace duckdb
|
|
@@ -98273,8 +98287,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
98273
98287
|
} catch (std::exception &ex) {
|
|
98274
98288
|
original_result->error = ex.what();
|
|
98275
98289
|
original_result->success = false;
|
|
98276
|
-
interrupted = false;
|
|
98277
98290
|
}
|
|
98291
|
+
interrupted = false;
|
|
98278
98292
|
|
|
98279
98293
|
// check explain, only if q does not already contain EXPLAIN
|
|
98280
98294
|
if (original_result->success) {
|
|
@@ -98294,8 +98308,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
98294
98308
|
} catch (std::exception &ex) {
|
|
98295
98309
|
copied_result->error = ex.what();
|
|
98296
98310
|
copied_result->success = false;
|
|
98297
|
-
interrupted = false;
|
|
98298
98311
|
}
|
|
98312
|
+
interrupted = false;
|
|
98299
98313
|
// now execute the deserialized statement
|
|
98300
98314
|
try {
|
|
98301
98315
|
auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false, false);
|
|
@@ -98303,8 +98317,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
98303
98317
|
} catch (std::exception &ex) {
|
|
98304
98318
|
deserialized_result->error = ex.what();
|
|
98305
98319
|
deserialized_result->success = false;
|
|
98306
|
-
interrupted = false;
|
|
98307
98320
|
}
|
|
98321
|
+
interrupted = false;
|
|
98308
98322
|
// now execute the unoptimized statement
|
|
98309
98323
|
config.enable_optimizer = false;
|
|
98310
98324
|
try {
|
|
@@ -98313,8 +98327,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
98313
98327
|
} catch (std::exception &ex) {
|
|
98314
98328
|
unoptimized_result->error = ex.what();
|
|
98315
98329
|
unoptimized_result->success = false;
|
|
98316
|
-
interrupted = false;
|
|
98317
98330
|
}
|
|
98331
|
+
interrupted = false;
|
|
98318
98332
|
config.enable_optimizer = true;
|
|
98319
98333
|
|
|
98320
98334
|
if (profiling_is_enabled) {
|
|
@@ -99884,6 +99898,7 @@ ExtensionLoadResult ExtensionHelper::LoadExtensionInternal(DuckDB &db, const std
|
|
|
99884
99898
|
|
|
99885
99899
|
|
|
99886
99900
|
|
|
99901
|
+
#ifndef DISABLE_DUCKDB_REMOTE_INSTALL
|
|
99887
99902
|
|
|
99888
99903
|
|
|
99889
99904
|
// LICENSE_CHANGE_BEGIN
|
|
@@ -107326,6 +107341,7 @@ inline SSL_CTX *Client::ssl_context() const {
|
|
|
107326
107341
|
|
|
107327
107342
|
// LICENSE_CHANGE_END
|
|
107328
107343
|
|
|
107344
|
+
#endif
|
|
107329
107345
|
|
|
107330
107346
|
|
|
107331
107347
|
#include <fstream>
|
|
@@ -107383,6 +107399,9 @@ void ExtensionHelper::InstallExtension(DatabaseInstance &db, const string &exten
|
|
|
107383
107399
|
throw IOException("Failed to read extension from \"%s\": no such file", extension);
|
|
107384
107400
|
}
|
|
107385
107401
|
|
|
107402
|
+
#ifdef DISABLE_DUCKDB_REMOTE_INSTALL
|
|
107403
|
+
throw BinderException("Remote extension installation is disabled through configuration");
|
|
107404
|
+
#else
|
|
107386
107405
|
string url_template = "http://extensions.duckdb.org/${REVISION}/${PLATFORM}/${NAME}.duckdb_extension.gz";
|
|
107387
107406
|
|
|
107388
107407
|
if (is_http_url) {
|
|
@@ -107421,6 +107440,7 @@ void ExtensionHelper::InstallExtension(DatabaseInstance &db, const string &exten
|
|
|
107421
107440
|
if (out.bad()) {
|
|
107422
107441
|
throw IOException("Failed to write extension to %s", local_extension_path);
|
|
107423
107442
|
}
|
|
107443
|
+
#endif
|
|
107424
107444
|
}
|
|
107425
107445
|
|
|
107426
107446
|
} // namespace duckdb
|
|
@@ -112829,7 +112849,10 @@ void ExpressionRewriter::VisitExpression(unique_ptr<Expression> *expression) {
|
|
|
112829
112849
|
|
|
112830
112850
|
|
|
112831
112851
|
|
|
112852
|
+
|
|
112853
|
+
|
|
112832
112854
|
#include <functional>
|
|
112855
|
+
#include <map>
|
|
112833
112856
|
|
|
112834
112857
|
namespace duckdb {
|
|
112835
112858
|
|
|
@@ -112867,6 +112890,37 @@ private:
|
|
|
112867
112890
|
idx_t GetEquivalenceSet(Expression *expr);
|
|
112868
112891
|
FilterResult AddConstantComparison(vector<ExpressionValueInformation> &info_list, ExpressionValueInformation info);
|
|
112869
112892
|
|
|
112893
|
+
//! Functions used to push and generate OR Filters
|
|
112894
|
+
void LookUpConjunctions(Expression *expr);
|
|
112895
|
+
bool BFSLookUpConjunctions(BoundConjunctionExpression *conjunction);
|
|
112896
|
+
void VerifyOrsToPush(Expression &expr);
|
|
112897
|
+
|
|
112898
|
+
bool UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr);
|
|
112899
|
+
bool UpdateFilterByColumn(BoundColumnRefExpression *column_ref, BoundComparisonExpression *comparison_expr);
|
|
112900
|
+
void GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids);
|
|
112901
|
+
|
|
112902
|
+
template <typename CONJUNCTION_TYPE>
|
|
112903
|
+
void GenerateConjunctionFilter(BoundConjunctionExpression *conjunction, ConjunctionFilter *last_conj_filter) {
|
|
112904
|
+
auto new_filter = NextConjunctionFilter<CONJUNCTION_TYPE>(conjunction);
|
|
112905
|
+
auto conj_filter_ptr = (ConjunctionFilter *)new_filter.get();
|
|
112906
|
+
last_conj_filter->child_filters.push_back(move(new_filter));
|
|
112907
|
+
last_conj_filter = conj_filter_ptr;
|
|
112908
|
+
}
|
|
112909
|
+
|
|
112910
|
+
template <typename CONJUNCTION_TYPE>
|
|
112911
|
+
unique_ptr<TableFilter> NextConjunctionFilter(BoundConjunctionExpression *conjunction) {
|
|
112912
|
+
unique_ptr<ConjunctionFilter> conj_filter = make_unique<CONJUNCTION_TYPE>();
|
|
112913
|
+
for (auto &expr : conjunction->children) {
|
|
112914
|
+
auto comp_expr = (BoundComparisonExpression *)expr.get();
|
|
112915
|
+
auto &const_expr =
|
|
112916
|
+
(comp_expr->left->type == ExpressionType::VALUE_CONSTANT) ? *comp_expr->left : *comp_expr->right;
|
|
112917
|
+
auto const_value = ExpressionExecutor::EvaluateScalar(const_expr);
|
|
112918
|
+
auto const_filter = make_unique<ConstantFilter>(comp_expr->type, const_value);
|
|
112919
|
+
conj_filter->child_filters.push_back(move(const_filter));
|
|
112920
|
+
}
|
|
112921
|
+
return move(conj_filter);
|
|
112922
|
+
}
|
|
112923
|
+
|
|
112870
112924
|
private:
|
|
112871
112925
|
vector<unique_ptr<Expression>> remaining_filters;
|
|
112872
112926
|
|
|
@@ -112875,6 +112929,26 @@ private:
|
|
|
112875
112929
|
unordered_map<idx_t, vector<ExpressionValueInformation>> constant_values;
|
|
112876
112930
|
unordered_map<idx_t, vector<Expression *>> equivalence_map;
|
|
112877
112931
|
idx_t set_index = 0;
|
|
112932
|
+
|
|
112933
|
+
//! Structures used for OR Filters
|
|
112934
|
+
|
|
112935
|
+
struct ConjunctionsToPush {
|
|
112936
|
+
BoundConjunctionExpression *root_or;
|
|
112937
|
+
|
|
112938
|
+
// only preserve AND if there is a single column in the expression
|
|
112939
|
+
bool preserve_and = true;
|
|
112940
|
+
|
|
112941
|
+
// conjunction chain for this column
|
|
112942
|
+
vector<unique_ptr<BoundConjunctionExpression>> conjunctions;
|
|
112943
|
+
};
|
|
112944
|
+
|
|
112945
|
+
expression_map_t<vector<unique_ptr<ConjunctionsToPush>>> map_col_conjunctions;
|
|
112946
|
+
vector<BoundColumnRefExpression *> vec_colref_insertion_order;
|
|
112947
|
+
|
|
112948
|
+
BoundConjunctionExpression *cur_root_or;
|
|
112949
|
+
BoundConjunctionExpression *cur_conjunction;
|
|
112950
|
+
|
|
112951
|
+
BoundColumnRefExpression *cur_colref_to_push;
|
|
112878
112952
|
};
|
|
112879
112953
|
|
|
112880
112954
|
} // namespace duckdb
|
|
@@ -112896,6 +112970,7 @@ private:
|
|
|
112896
112970
|
|
|
112897
112971
|
|
|
112898
112972
|
|
|
112973
|
+
|
|
112899
112974
|
namespace duckdb {
|
|
112900
112975
|
|
|
112901
112976
|
using ExpressionValueInformation = FilterCombiner::ExpressionValueInformation;
|
|
@@ -112958,6 +113033,7 @@ FilterResult FilterCombiner::AddConstantComparison(vector<ExpressionValueInforma
|
|
|
112958
113033
|
}
|
|
112959
113034
|
|
|
112960
113035
|
FilterResult FilterCombiner::AddFilter(unique_ptr<Expression> expr) {
|
|
113036
|
+
LookUpConjunctions(expr.get());
|
|
112961
113037
|
// try to push the filter into the combiner
|
|
112962
113038
|
auto result = AddFilter(expr.get());
|
|
112963
113039
|
if (result == FilterResult::UNSUPPORTED) {
|
|
@@ -113430,6 +113506,8 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
|
|
|
113430
113506
|
}
|
|
113431
113507
|
}
|
|
113432
113508
|
|
|
113509
|
+
GenerateORFilters(table_filters, column_ids);
|
|
113510
|
+
|
|
113433
113511
|
return table_filters;
|
|
113434
113512
|
}
|
|
113435
113513
|
|
|
@@ -113867,6 +113945,176 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left,
|
|
|
113867
113945
|
}
|
|
113868
113946
|
}
|
|
113869
113947
|
|
|
113948
|
+
void FilterCombiner::LookUpConjunctions(Expression *expr) {
|
|
113949
|
+
if (expr->GetExpressionType() == ExpressionType::CONJUNCTION_OR) {
|
|
113950
|
+
auto root_or_expr = (BoundConjunctionExpression *)expr;
|
|
113951
|
+
for (const auto &entry : map_col_conjunctions) {
|
|
113952
|
+
for (const auto &conjs_to_push : entry.second) {
|
|
113953
|
+
if (conjs_to_push->root_or->Equals(root_or_expr)) {
|
|
113954
|
+
return;
|
|
113955
|
+
}
|
|
113956
|
+
}
|
|
113957
|
+
}
|
|
113958
|
+
|
|
113959
|
+
cur_root_or = root_or_expr;
|
|
113960
|
+
cur_conjunction = root_or_expr;
|
|
113961
|
+
cur_colref_to_push = nullptr;
|
|
113962
|
+
if (!BFSLookUpConjunctions(cur_root_or)) {
|
|
113963
|
+
if (cur_colref_to_push) {
|
|
113964
|
+
auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
113965
|
+
auto &vec_conjs_to_push = entry->second;
|
|
113966
|
+
if (vec_conjs_to_push.size() == 1) {
|
|
113967
|
+
map_col_conjunctions.erase(entry);
|
|
113968
|
+
return;
|
|
113969
|
+
}
|
|
113970
|
+
vec_conjs_to_push.pop_back();
|
|
113971
|
+
}
|
|
113972
|
+
}
|
|
113973
|
+
return;
|
|
113974
|
+
}
|
|
113975
|
+
|
|
113976
|
+
// Verify if the expression has a column already pushed down by other OR expression
|
|
113977
|
+
VerifyOrsToPush(*expr);
|
|
113978
|
+
}
|
|
113979
|
+
|
|
113980
|
+
bool FilterCombiner::BFSLookUpConjunctions(BoundConjunctionExpression *conjunction) {
|
|
113981
|
+
vector<BoundConjunctionExpression *> conjunctions_to_visit;
|
|
113982
|
+
|
|
113983
|
+
for (auto &child : conjunction->children) {
|
|
113984
|
+
switch (child->GetExpressionClass()) {
|
|
113985
|
+
case ExpressionClass::BOUND_CONJUNCTION: {
|
|
113986
|
+
auto child_conjunction = (BoundConjunctionExpression *)child.get();
|
|
113987
|
+
conjunctions_to_visit.emplace_back(child_conjunction);
|
|
113988
|
+
break;
|
|
113989
|
+
}
|
|
113990
|
+
case ExpressionClass::BOUND_COMPARISON: {
|
|
113991
|
+
if (!UpdateConjunctionFilter((BoundComparisonExpression *)child.get())) {
|
|
113992
|
+
return false;
|
|
113993
|
+
}
|
|
113994
|
+
break;
|
|
113995
|
+
}
|
|
113996
|
+
default: {
|
|
113997
|
+
return false;
|
|
113998
|
+
}
|
|
113999
|
+
}
|
|
114000
|
+
}
|
|
114001
|
+
|
|
114002
|
+
for (auto child_conjunction : conjunctions_to_visit) {
|
|
114003
|
+
cur_conjunction = child_conjunction;
|
|
114004
|
+
// traverse child conjuction
|
|
114005
|
+
if (!BFSLookUpConjunctions(child_conjunction)) {
|
|
114006
|
+
return false;
|
|
114007
|
+
}
|
|
114008
|
+
}
|
|
114009
|
+
return true;
|
|
114010
|
+
}
|
|
114011
|
+
|
|
114012
|
+
void FilterCombiner::VerifyOrsToPush(Expression &expr) {
|
|
114013
|
+
if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
|
|
114014
|
+
auto colref = (BoundColumnRefExpression *)&expr;
|
|
114015
|
+
auto entry = map_col_conjunctions.find(colref);
|
|
114016
|
+
if (entry == map_col_conjunctions.end()) {
|
|
114017
|
+
return;
|
|
114018
|
+
}
|
|
114019
|
+
map_col_conjunctions.erase(entry);
|
|
114020
|
+
}
|
|
114021
|
+
ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { VerifyOrsToPush(child); });
|
|
114022
|
+
}
|
|
114023
|
+
|
|
114024
|
+
bool FilterCombiner::UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr) {
|
|
114025
|
+
bool left_is_scalar = comparison_expr->left->IsFoldable();
|
|
114026
|
+
bool right_is_scalar = comparison_expr->right->IsFoldable();
|
|
114027
|
+
|
|
114028
|
+
Expression *non_scalar_expr;
|
|
114029
|
+
if (left_is_scalar || right_is_scalar) {
|
|
114030
|
+
// only support comparison with scalar
|
|
114031
|
+
non_scalar_expr = left_is_scalar ? comparison_expr->right.get() : comparison_expr->left.get();
|
|
114032
|
+
|
|
114033
|
+
if (non_scalar_expr->GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) {
|
|
114034
|
+
return UpdateFilterByColumn((BoundColumnRefExpression *)non_scalar_expr, comparison_expr);
|
|
114035
|
+
}
|
|
114036
|
+
}
|
|
114037
|
+
|
|
114038
|
+
return false;
|
|
114039
|
+
}
|
|
114040
|
+
|
|
114041
|
+
bool FilterCombiner::UpdateFilterByColumn(BoundColumnRefExpression *column_ref,
|
|
114042
|
+
BoundComparisonExpression *comparison_expr) {
|
|
114043
|
+
if (cur_colref_to_push == nullptr) {
|
|
114044
|
+
cur_colref_to_push = column_ref;
|
|
114045
|
+
|
|
114046
|
+
auto or_conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_OR);
|
|
114047
|
+
or_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
114048
|
+
|
|
114049
|
+
unique_ptr<ConjunctionsToPush> conjs_to_push = make_unique<ConjunctionsToPush>();
|
|
114050
|
+
conjs_to_push->conjunctions.emplace_back(move(or_conjunction));
|
|
114051
|
+
conjs_to_push->root_or = cur_root_or;
|
|
114052
|
+
|
|
114053
|
+
auto &&vec_col_conjs = map_col_conjunctions[column_ref];
|
|
114054
|
+
vec_col_conjs.emplace_back(move(conjs_to_push));
|
|
114055
|
+
vec_colref_insertion_order.emplace_back(column_ref);
|
|
114056
|
+
return true;
|
|
114057
|
+
}
|
|
114058
|
+
|
|
114059
|
+
auto entry = map_col_conjunctions.find(cur_colref_to_push);
|
|
114060
|
+
D_ASSERT(entry != map_col_conjunctions.end());
|
|
114061
|
+
auto &conjunctions_to_push = entry->second.back();
|
|
114062
|
+
|
|
114063
|
+
if (!cur_colref_to_push->Equals(column_ref)) {
|
|
114064
|
+
// check for multiple colunms in the same root OR node
|
|
114065
|
+
if (cur_root_or == cur_conjunction) {
|
|
114066
|
+
return false;
|
|
114067
|
+
}
|
|
114068
|
+
// found an AND using a different column, we should stop the look up
|
|
114069
|
+
if (cur_conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
|
|
114070
|
+
return false;
|
|
114071
|
+
}
|
|
114072
|
+
|
|
114073
|
+
// found a different column, AND conditions cannot be preserved anymore
|
|
114074
|
+
conjunctions_to_push->preserve_and = false;
|
|
114075
|
+
return true;
|
|
114076
|
+
}
|
|
114077
|
+
|
|
114078
|
+
auto &last_conjunction = conjunctions_to_push->conjunctions.back();
|
|
114079
|
+
if (cur_conjunction->GetExpressionType() == last_conjunction->GetExpressionType()) {
|
|
114080
|
+
last_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
114081
|
+
} else {
|
|
114082
|
+
auto new_conjunction = make_unique<BoundConjunctionExpression>(cur_conjunction->GetExpressionType());
|
|
114083
|
+
new_conjunction->children.emplace_back(comparison_expr->Copy());
|
|
114084
|
+
conjunctions_to_push->conjunctions.emplace_back(move(new_conjunction));
|
|
114085
|
+
}
|
|
114086
|
+
return true;
|
|
114087
|
+
}
|
|
114088
|
+
|
|
114089
|
+
void FilterCombiner::GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids) {
|
|
114090
|
+
for (const auto colref : vec_colref_insertion_order) {
|
|
114091
|
+
auto column_index = column_ids[colref->binding.column_index];
|
|
114092
|
+
if (column_index == COLUMN_IDENTIFIER_ROW_ID) {
|
|
114093
|
+
break;
|
|
114094
|
+
}
|
|
114095
|
+
|
|
114096
|
+
for (const auto &conjunctions_to_push : map_col_conjunctions[colref]) {
|
|
114097
|
+
// root OR filter to push into the TableFilter
|
|
114098
|
+
auto root_or_filter = make_unique<ConjunctionOrFilter>();
|
|
114099
|
+
// variable to hold the last conjuntion filter pointer
|
|
114100
|
+
// the next filter will be added into it, i.e., we create a chain of conjunction filters
|
|
114101
|
+
ConjunctionFilter *last_conj_filter = root_or_filter.get();
|
|
114102
|
+
|
|
114103
|
+
for (auto &conjunction : conjunctions_to_push->conjunctions) {
|
|
114104
|
+
if (conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND &&
|
|
114105
|
+
conjunctions_to_push->preserve_and) {
|
|
114106
|
+
GenerateConjunctionFilter<ConjunctionAndFilter>(conjunction.get(), last_conj_filter);
|
|
114107
|
+
} else {
|
|
114108
|
+
GenerateConjunctionFilter<ConjunctionOrFilter>(conjunction.get(), last_conj_filter);
|
|
114109
|
+
}
|
|
114110
|
+
}
|
|
114111
|
+
table_filter.PushFilter(column_index, move(root_or_filter));
|
|
114112
|
+
}
|
|
114113
|
+
}
|
|
114114
|
+
map_col_conjunctions.clear();
|
|
114115
|
+
vec_colref_insertion_order.clear();
|
|
114116
|
+
}
|
|
114117
|
+
|
|
113870
114118
|
} // namespace duckdb
|
|
113871
114119
|
//===----------------------------------------------------------------------===//
|
|
113872
114120
|
// DuckDB
|
|
@@ -119003,6 +119251,10 @@ FilterPropagateResult StatisticsPropagator::PropagateComparison(BaseStatistics &
|
|
|
119003
119251
|
// only handle numerics for now
|
|
119004
119252
|
switch (left.type.InternalType()) {
|
|
119005
119253
|
case PhysicalType::BOOL:
|
|
119254
|
+
case PhysicalType::UINT8:
|
|
119255
|
+
case PhysicalType::UINT16:
|
|
119256
|
+
case PhysicalType::UINT32:
|
|
119257
|
+
case PhysicalType::UINT64:
|
|
119006
119258
|
case PhysicalType::INT8:
|
|
119007
119259
|
case PhysicalType::INT16:
|
|
119008
119260
|
case PhysicalType::INT32:
|
|
@@ -119130,6 +119382,10 @@ namespace duckdb {
|
|
|
119130
119382
|
unique_ptr<BaseStatistics> StatisticsPropagator::StatisticsFromValue(const Value &input) {
|
|
119131
119383
|
switch (input.type().InternalType()) {
|
|
119132
119384
|
case PhysicalType::BOOL:
|
|
119385
|
+
case PhysicalType::UINT8:
|
|
119386
|
+
case PhysicalType::UINT16:
|
|
119387
|
+
case PhysicalType::UINT32:
|
|
119388
|
+
case PhysicalType::UINT64:
|
|
119133
119389
|
case PhysicalType::INT8:
|
|
119134
119390
|
case PhysicalType::INT16:
|
|
119135
119391
|
case PhysicalType::INT32:
|
|
@@ -138758,7 +139014,8 @@ unique_ptr<CreateStatement> Transformer::TransformCreateFunction(duckdb_libpgque
|
|
|
138758
139014
|
if (macro_func->default_parameters.find(param->alias) != macro_func->default_parameters.end()) {
|
|
138759
139015
|
throw ParserException("Duplicate default parameter: '%s'", param->alias);
|
|
138760
139016
|
}
|
|
138761
|
-
|
|
139017
|
+
auto alias = param->alias;
|
|
139018
|
+
macro_func->default_parameters[alias] = move(param);
|
|
138762
139019
|
} else if (param->GetExpressionClass() == ExpressionClass::COLUMN_REF) {
|
|
138763
139020
|
// positional parameters
|
|
138764
139021
|
if (!macro_func->default_parameters.empty()) {
|
|
@@ -149818,7 +150075,7 @@ void ExpressionIterator::EnumerateQueryNodeChildren(BoundQueryNode &node,
|
|
|
149818
150075
|
|
|
149819
150076
|
namespace duckdb {
|
|
149820
150077
|
|
|
149821
|
-
ConjunctionOrFilter::ConjunctionOrFilter() :
|
|
150078
|
+
ConjunctionOrFilter::ConjunctionOrFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_OR) {
|
|
149822
150079
|
}
|
|
149823
150080
|
|
|
149824
150081
|
FilterPropagateResult ConjunctionOrFilter::CheckStatistics(BaseStatistics &stats) {
|
|
@@ -149847,7 +150104,7 @@ string ConjunctionOrFilter::ToString(const string &column_name) {
|
|
|
149847
150104
|
}
|
|
149848
150105
|
|
|
149849
150106
|
bool ConjunctionOrFilter::Equals(const TableFilter &other_p) const {
|
|
149850
|
-
if (!
|
|
150107
|
+
if (!ConjunctionFilter::Equals(other_p)) {
|
|
149851
150108
|
return false;
|
|
149852
150109
|
}
|
|
149853
150110
|
auto &other = (ConjunctionOrFilter &)other_p;
|
|
@@ -149862,11 +150119,11 @@ bool ConjunctionOrFilter::Equals(const TableFilter &other_p) const {
|
|
|
149862
150119
|
return true;
|
|
149863
150120
|
}
|
|
149864
150121
|
|
|
149865
|
-
ConjunctionAndFilter::ConjunctionAndFilter() :
|
|
150122
|
+
ConjunctionAndFilter::ConjunctionAndFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_AND) {
|
|
149866
150123
|
}
|
|
149867
150124
|
|
|
149868
150125
|
FilterPropagateResult ConjunctionAndFilter::CheckStatistics(BaseStatistics &stats) {
|
|
149869
|
-
// the
|
|
150126
|
+
// the AND filter is true if ALL of the children is true
|
|
149870
150127
|
D_ASSERT(!child_filters.empty());
|
|
149871
150128
|
auto result = FilterPropagateResult::FILTER_ALWAYS_TRUE;
|
|
149872
150129
|
for (auto &filter : child_filters) {
|
|
@@ -149892,7 +150149,7 @@ string ConjunctionAndFilter::ToString(const string &column_name) {
|
|
|
149892
150149
|
}
|
|
149893
150150
|
|
|
149894
150151
|
bool ConjunctionAndFilter::Equals(const TableFilter &other_p) const {
|
|
149895
|
-
if (!
|
|
150152
|
+
if (!ConjunctionFilter::Equals(other_p)) {
|
|
149896
150153
|
return false;
|
|
149897
150154
|
}
|
|
149898
150155
|
auto &other = (ConjunctionAndFilter &)other_p;
|
|
@@ -160109,6 +160366,14 @@ FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_
|
|
|
160109
160366
|
} else {
|
|
160110
160367
|
return FilterPropagateResult::FILTER_ALWAYS_FALSE;
|
|
160111
160368
|
}
|
|
160369
|
+
case ExpressionType::COMPARE_NOTEQUAL:
|
|
160370
|
+
if (constant < min || constant > max) {
|
|
160371
|
+
return FilterPropagateResult::FILTER_ALWAYS_TRUE;
|
|
160372
|
+
} else if (min == max && min == constant) {
|
|
160373
|
+
// corner case of a cluster with one numeric equal to the target constant
|
|
160374
|
+
return FilterPropagateResult::FILTER_ALWAYS_FALSE;
|
|
160375
|
+
}
|
|
160376
|
+
return FilterPropagateResult::NO_PRUNING_POSSIBLE;
|
|
160112
160377
|
case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
|
|
160113
160378
|
// X >= C
|
|
160114
160379
|
// this can be true only if max(X) >= C
|
|
@@ -160305,7 +160570,6 @@ unique_ptr<BaseStatistics> StringStatistics::Copy() {
|
|
|
160305
160570
|
memcpy(stats->max, max, MAX_STRING_MINMAX_SIZE);
|
|
160306
160571
|
stats->has_unicode = has_unicode;
|
|
160307
160572
|
stats->max_string_length = max_string_length;
|
|
160308
|
-
stats->max_string_length = max_string_length;
|
|
160309
160573
|
if (validity_stats) {
|
|
160310
160574
|
stats->validity_stats = validity_stats->Copy();
|
|
160311
160575
|
}
|
|
@@ -160409,6 +160673,11 @@ FilterPropagateResult StringStatistics::CheckZonemap(ExpressionType comparison_t
|
|
|
160409
160673
|
} else {
|
|
160410
160674
|
return FilterPropagateResult::FILTER_ALWAYS_FALSE;
|
|
160411
160675
|
}
|
|
160676
|
+
case ExpressionType::COMPARE_NOTEQUAL:
|
|
160677
|
+
if (min_comp < 0 || max_comp > 0) {
|
|
160678
|
+
return FilterPropagateResult::FILTER_ALWAYS_TRUE;
|
|
160679
|
+
}
|
|
160680
|
+
return FilterPropagateResult::NO_PRUNING_POSSIBLE;
|
|
160412
160681
|
case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
|
|
160413
160682
|
case ExpressionType::COMPARE_GREATERTHAN:
|
|
160414
160683
|
if (max_comp <= 0) {
|
|
@@ -162532,6 +162801,16 @@ static void FilterSelectionSwitch(T *vec, T *predicate, SelectionVector &sel, id
|
|
|
162532
162801
|
}
|
|
162533
162802
|
break;
|
|
162534
162803
|
}
|
|
162804
|
+
case ExpressionType::COMPARE_NOTEQUAL: {
|
|
162805
|
+
if (mask.AllValid()) {
|
|
162806
|
+
approved_tuple_count =
|
|
162807
|
+
TemplatedFilterSelection<T, NotEquals, false>(vec, predicate, sel, approved_tuple_count, mask, new_sel);
|
|
162808
|
+
} else {
|
|
162809
|
+
approved_tuple_count =
|
|
162810
|
+
TemplatedFilterSelection<T, NotEquals, true>(vec, predicate, sel, approved_tuple_count, mask, new_sel);
|
|
162811
|
+
}
|
|
162812
|
+
break;
|
|
162813
|
+
}
|
|
162535
162814
|
case ExpressionType::COMPARE_LESSTHAN: {
|
|
162536
162815
|
if (mask.AllValid()) {
|
|
162537
162816
|
approved_tuple_count =
|
|
@@ -162601,15 +162880,44 @@ static idx_t TemplatedNullSelection(SelectionVector &sel, idx_t approved_tuple_c
|
|
|
162601
162880
|
}
|
|
162602
162881
|
}
|
|
162603
162882
|
|
|
162604
|
-
|
|
162605
|
-
|
|
162883
|
+
idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter,
|
|
162884
|
+
idx_t &approved_tuple_count, ValidityMask &mask) {
|
|
162606
162885
|
switch (filter.filter_type) {
|
|
162886
|
+
case TableFilterType::CONJUNCTION_OR: {
|
|
162887
|
+
// similar to the CONJUNCTION_AND, but we need to take care of the SelectionVectors (OR all of them)
|
|
162888
|
+
idx_t count_total = 0;
|
|
162889
|
+
SelectionVector result_sel(approved_tuple_count);
|
|
162890
|
+
auto &conjunction_or = (ConjunctionOrFilter &)filter;
|
|
162891
|
+
for (auto &child_filter : conjunction_or.child_filters) {
|
|
162892
|
+
SelectionVector temp_sel;
|
|
162893
|
+
temp_sel.Initialize(sel);
|
|
162894
|
+
idx_t temp_tuple_count = approved_tuple_count;
|
|
162895
|
+
idx_t temp_count = FilterSelection(temp_sel, result, *child_filter, temp_tuple_count, mask);
|
|
162896
|
+
// tuples passed, move them into the actual result vector
|
|
162897
|
+
for (idx_t i = 0; i < temp_count; i++) {
|
|
162898
|
+
auto new_idx = temp_sel.get_index(i);
|
|
162899
|
+
bool is_new_idx = true;
|
|
162900
|
+
for (idx_t res_idx = 0; res_idx < count_total; res_idx++) {
|
|
162901
|
+
if (result_sel.get_index(res_idx) == new_idx) {
|
|
162902
|
+
is_new_idx = false;
|
|
162903
|
+
break;
|
|
162904
|
+
}
|
|
162905
|
+
}
|
|
162906
|
+
if (is_new_idx) {
|
|
162907
|
+
result_sel.set_index(count_total++, new_idx);
|
|
162908
|
+
}
|
|
162909
|
+
}
|
|
162910
|
+
}
|
|
162911
|
+
sel.Initialize(result_sel);
|
|
162912
|
+
approved_tuple_count = count_total;
|
|
162913
|
+
return approved_tuple_count;
|
|
162914
|
+
}
|
|
162607
162915
|
case TableFilterType::CONJUNCTION_AND: {
|
|
162608
162916
|
auto &conjunction_and = (ConjunctionAndFilter &)filter;
|
|
162609
162917
|
for (auto &child_filter : conjunction_and.child_filters) {
|
|
162610
162918
|
FilterSelection(sel, result, *child_filter, approved_tuple_count, mask);
|
|
162611
162919
|
}
|
|
162612
|
-
|
|
162920
|
+
return approved_tuple_count;
|
|
162613
162921
|
}
|
|
162614
162922
|
case TableFilterType::CONSTANT_COMPARISON: {
|
|
162615
162923
|
auto &constant_filter = (ConstantFilter &)filter;
|
|
@@ -162722,14 +163030,12 @@ void ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const
|
|
|
162722
163030
|
default:
|
|
162723
163031
|
throw InvalidTypeException(result.GetType(), "Invalid type for filter pushed down to table comparison");
|
|
162724
163032
|
}
|
|
162725
|
-
|
|
163033
|
+
return approved_tuple_count;
|
|
162726
163034
|
}
|
|
162727
163035
|
case TableFilterType::IS_NULL:
|
|
162728
|
-
TemplatedNullSelection<true>(sel, approved_tuple_count, mask);
|
|
162729
|
-
break;
|
|
163036
|
+
return TemplatedNullSelection<true>(sel, approved_tuple_count, mask);
|
|
162730
163037
|
case TableFilterType::IS_NOT_NULL:
|
|
162731
|
-
TemplatedNullSelection<false>(sel, approved_tuple_count, mask);
|
|
162732
|
-
break;
|
|
163038
|
+
return TemplatedNullSelection<false>(sel, approved_tuple_count, mask);
|
|
162733
163039
|
default:
|
|
162734
163040
|
throw InternalException("FIXME: unsupported type for filter selection");
|
|
162735
163041
|
}
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "0.3.2-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "542f5d599"
|
|
15
|
+
#define DUCKDB_VERSION "0.3.2-dev838"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
|
@@ -1097,6 +1097,11 @@ struct StructType {
|
|
|
1097
1097
|
DUCKDB_API static idx_t GetChildCount(const LogicalType &type);
|
|
1098
1098
|
};
|
|
1099
1099
|
|
|
1100
|
+
struct MapType {
|
|
1101
|
+
DUCKDB_API static const LogicalType &KeyType(const LogicalType &type);
|
|
1102
|
+
DUCKDB_API static const LogicalType &ValueType(const LogicalType &type);
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1100
1105
|
|
|
1101
1106
|
string LogicalTypeIdToString(LogicalTypeId type);
|
|
1102
1107
|
|
|
@@ -19200,8 +19205,8 @@ public:
|
|
|
19200
19205
|
//! Fetch a value of the specific row id and append it to the result
|
|
19201
19206
|
void FetchRow(ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx);
|
|
19202
19207
|
|
|
19203
|
-
static
|
|
19204
|
-
|
|
19208
|
+
static idx_t FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter,
|
|
19209
|
+
idx_t &approved_tuple_count, ValidityMask &mask);
|
|
19205
19210
|
|
|
19206
19211
|
//! Skip a scan forward to the row_index specified in the scan state
|
|
19207
19212
|
void Skip(ColumnScanState &state);
|
|
@@ -20102,27 +20107,40 @@ void NumericStatistics::Update<list_entry_t>(SegmentStatistics &stats, list_entr
|
|
|
20102
20107
|
|
|
20103
20108
|
|
|
20104
20109
|
namespace duckdb {
|
|
20105
|
-
|
|
20106
|
-
class ConjunctionOrFilter : public TableFilter {
|
|
20110
|
+
class ConjunctionFilter : public TableFilter {
|
|
20107
20111
|
public:
|
|
20108
|
-
|
|
20112
|
+
ConjunctionFilter(TableFilterType filter_type_p) : TableFilter(filter_type_p) {
|
|
20113
|
+
}
|
|
20109
20114
|
|
|
20110
|
-
|
|
20115
|
+
virtual ~ConjunctionFilter() {
|
|
20116
|
+
}
|
|
20117
|
+
|
|
20118
|
+
//! The filters of this conjunction
|
|
20111
20119
|
vector<unique_ptr<TableFilter>> child_filters;
|
|
20112
20120
|
|
|
20121
|
+
public:
|
|
20122
|
+
virtual FilterPropagateResult CheckStatistics(BaseStatistics &stats) = 0;
|
|
20123
|
+
virtual string ToString(const string &column_name) = 0;
|
|
20124
|
+
|
|
20125
|
+
virtual bool Equals(const TableFilter &other) const {
|
|
20126
|
+
return TableFilter::Equals(other);
|
|
20127
|
+
}
|
|
20128
|
+
};
|
|
20129
|
+
|
|
20130
|
+
class ConjunctionOrFilter : public ConjunctionFilter {
|
|
20131
|
+
public:
|
|
20132
|
+
ConjunctionOrFilter();
|
|
20133
|
+
|
|
20113
20134
|
public:
|
|
20114
20135
|
FilterPropagateResult CheckStatistics(BaseStatistics &stats) override;
|
|
20115
20136
|
string ToString(const string &column_name) override;
|
|
20116
20137
|
bool Equals(const TableFilter &other) const override;
|
|
20117
20138
|
};
|
|
20118
20139
|
|
|
20119
|
-
class ConjunctionAndFilter : public
|
|
20140
|
+
class ConjunctionAndFilter : public ConjunctionFilter {
|
|
20120
20141
|
public:
|
|
20121
20142
|
ConjunctionAndFilter();
|
|
20122
20143
|
|
|
20123
|
-
//! The filters to OR together
|
|
20124
|
-
vector<unique_ptr<TableFilter>> child_filters;
|
|
20125
|
-
|
|
20126
20144
|
public:
|
|
20127
20145
|
FilterPropagateResult CheckStatistics(BaseStatistics &stats) override;
|
|
20128
20146
|
string ToString(const string &column_name) override;
|