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 | |
9 | namespace duckdb { |
10 | |
11 | CreateViewInfo::CreateViewInfo() : CreateInfo(CatalogType::VIEW_ENTRY, INVALID_SCHEMA) { |
12 | } |
13 | CreateViewInfo::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 | |
18 | CreateViewInfo::CreateViewInfo(SchemaCatalogEntry &schema, string view_name) |
19 | : CreateViewInfo(schema.catalog.GetName(), schema.name, std::move(view_name)) { |
20 | } |
21 | |
22 | unique_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 | |
31 | unique_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 | |
45 | void 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 | |
54 | unique_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 | |
76 | unique_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 | |