1#include "duckdb/parser/parsed_data/create_view_info.hpp"
2#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp"
3#include "duckdb/catalog/catalog.hpp"
4#include "duckdb/parser/parser.hpp"
5#include "duckdb/planner/binder.hpp"
6#include "duckdb/parser/statement/select_statement.hpp"
7#include "duckdb/parser/statement/create_statement.hpp"
8
9namespace duckdb {
10
11CreateViewInfo::CreateViewInfo() : CreateInfo(CatalogType::VIEW_ENTRY, INVALID_SCHEMA) {
12}
13CreateViewInfo::CreateViewInfo(string catalog_p, string schema_p, string view_name_p)
14 : CreateInfo(CatalogType::VIEW_ENTRY, std::move(schema_p), std::move(catalog_p)),
15 view_name(std::move(view_name_p)) {
16}
17
18CreateViewInfo::CreateViewInfo(SchemaCatalogEntry &schema, string view_name)
19 : CreateViewInfo(schema.catalog.GetName(), schema.name, std::move(view_name)) {
20}
21
22unique_ptr<CreateInfo> CreateViewInfo::Copy() const {
23 auto result = make_uniq<CreateViewInfo>(args: catalog, args: schema, args: view_name);
24 CopyProperties(other&: *result);
25 result->aliases = aliases;
26 result->types = types;
27 result->query = unique_ptr_cast<SQLStatement, SelectStatement>(src: query->Copy());
28 return std::move(result);
29}
30
31unique_ptr<CreateViewInfo> CreateViewInfo::Deserialize(Deserializer &deserializer) {
32 auto result = make_uniq<CreateViewInfo>();
33 result->DeserializeBase(deserializer);
34
35 FieldReader reader(deserializer);
36 result->view_name = reader.ReadRequired<string>();
37 result->aliases = reader.ReadRequiredList<string>();
38 result->types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
39 result->query = reader.ReadOptional<SelectStatement>(default_value: nullptr);
40 reader.Finalize();
41
42 return result;
43}
44
45void CreateViewInfo::SerializeInternal(Serializer &serializer) const {
46 FieldWriter writer(serializer);
47 writer.WriteString(val: view_name);
48 writer.WriteList<string>(elements: aliases);
49 writer.WriteRegularSerializableList(elements: types);
50 writer.WriteOptional(element: query);
51 writer.Finalize();
52}
53
54unique_ptr<CreateViewInfo> CreateViewInfo::FromSelect(ClientContext &context, unique_ptr<CreateViewInfo> info) {
55 D_ASSERT(info);
56 D_ASSERT(!info->view_name.empty());
57 D_ASSERT(!info->sql.empty());
58 D_ASSERT(!info->query);
59
60 Parser parser;
61 parser.ParseQuery(query: info->sql);
62 if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) {
63 throw BinderException(
64 "Failed to create view from SQL string - \"%s\" - statement did not contain a single SELECT statement",
65 info->sql);
66 }
67 D_ASSERT(parser.statements.size() == 1 && parser.statements[0]->type == StatementType::SELECT_STATEMENT);
68 info->query = unique_ptr_cast<SQLStatement, SelectStatement>(src: std::move(parser.statements[0]));
69
70 auto binder = Binder::CreateBinder(context);
71 binder->BindCreateViewInfo(base&: *info);
72
73 return info;
74}
75
76unique_ptr<CreateViewInfo> CreateViewInfo::FromCreateView(ClientContext &context, const string &sql) {
77 D_ASSERT(!sql.empty());
78
79 // parse the SQL statement
80 Parser parser;
81 parser.ParseQuery(query: sql);
82
83 if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::CREATE_STATEMENT) {
84 throw BinderException(
85 "Failed to create view from SQL string - \"%s\" - statement did not contain a single CREATE VIEW statement",
86 sql);
87 }
88 auto &create_statement = parser.statements[0]->Cast<CreateStatement>();
89 if (create_statement.info->type != CatalogType::VIEW_ENTRY) {
90 throw BinderException(
91 "Failed to create view from SQL string - \"%s\" - view did not contain a CREATE VIEW statement", sql);
92 }
93
94 auto result = unique_ptr_cast<CreateInfo, CreateViewInfo>(src: std::move(create_statement.info));
95
96 auto binder = Binder::CreateBinder(context);
97 binder->BindCreateViewInfo(base&: *result);
98
99 return result;
100}
101
102} // namespace duckdb
103