Packages

An Elixir DuckDB library

Current section

Files

Jump to
exduckdb c_src duckdb src parser query_node.cpp
Raw

c_src/duckdb/src/parser/query_node.cpp

#include "duckdb/parser/query_node.hpp"
#include "duckdb/parser/query_node/select_node.hpp"
#include "duckdb/parser/query_node/set_operation_node.hpp"
#include "duckdb/parser/query_node/recursive_cte_node.hpp"
#include "duckdb/common/limits.hpp"
namespace duckdb {
bool QueryNode::Equals(const QueryNode *other) const {
if (!other) {
return false;
}
if (this == other) {
return true;
}
if (other->type != this->type) {
return false;
}
if (modifiers.size() != other->modifiers.size()) {
return false;
}
for (idx_t i = 0; i < modifiers.size(); i++) {
if (!modifiers[i]->Equals(other->modifiers[i].get())) {
return false;
}
}
// WITH clauses (CTEs)
if (cte_map.size() != other->cte_map.size()) {
return false;
}
for (auto &entry : cte_map) {
auto other_entry = other->cte_map.find(entry.first);
if (other_entry == other->cte_map.end()) {
return false;
}
if (entry.second->aliases != other_entry->second->aliases) {
return false;
}
if (!entry.second->query->Equals(other_entry->second->query.get())) {
return false;
}
}
return other->type == type;
}
void QueryNode::CopyProperties(QueryNode &other) const {
for (auto &modifier : modifiers) {
other.modifiers.push_back(modifier->Copy());
}
for (auto &kv : cte_map) {
auto kv_info = make_unique<CommonTableExpressionInfo>();
for (auto &al : kv.second->aliases) {
kv_info->aliases.push_back(al);
}
kv_info->query = unique_ptr_cast<SQLStatement, SelectStatement>(kv.second->query->Copy());
other.cte_map[kv.first] = move(kv_info);
}
}
void QueryNode::Serialize(Serializer &serializer) {
serializer.Write<QueryNodeType>(type);
serializer.Write<idx_t>(modifiers.size());
for (idx_t i = 0; i < modifiers.size(); i++) {
modifiers[i]->Serialize(serializer);
}
// cte_map
D_ASSERT(cte_map.size() <= NumericLimits<uint32_t>::Maximum());
serializer.Write<uint32_t>((uint32_t)cte_map.size());
for (auto &cte : cte_map) {
serializer.WriteString(cte.first);
serializer.WriteStringVector(cte.second->aliases);
cte.second->query->Serialize(serializer);
}
}
unique_ptr<QueryNode> QueryNode::Deserialize(Deserializer &source) {
unique_ptr<QueryNode> result;
auto type = source.Read<QueryNodeType>();
auto modifier_count = source.Read<idx_t>();
vector<unique_ptr<ResultModifier>> modifiers;
for (idx_t i = 0; i < modifier_count; i++) {
modifiers.push_back(ResultModifier::Deserialize(source));
}
// cte_map
auto cte_count = source.Read<uint32_t>();
unordered_map<string, unique_ptr<CommonTableExpressionInfo>> cte_map;
for (idx_t i = 0; i < cte_count; i++) {
auto name = source.Read<string>();
auto info = make_unique<CommonTableExpressionInfo>();
source.ReadStringVector(info->aliases);
info->query = SelectStatement::Deserialize(source);
cte_map[name] = move(info);
}
switch (type) {
case QueryNodeType::SELECT_NODE:
result = SelectNode::Deserialize(source);
break;
case QueryNodeType::SET_OPERATION_NODE:
result = SetOperationNode::Deserialize(source);
break;
case QueryNodeType::RECURSIVE_CTE_NODE:
result = RecursiveCTENode::Deserialize(source);
break;
default:
throw SerializationException("Could not deserialize Query Node: unknown type!");
}
result->modifiers = move(modifiers);
result->cte_map = move(cte_map);
return result;
}
} // namespace duckdb