| 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 | |