1#include "duckdb/parser/statement/drop_statement.hpp"
2#include "duckdb/parser/transformer.hpp"
3
4namespace duckdb {
5
6unique_ptr<SQLStatement> Transformer::TransformDrop(duckdb_libpgquery::PGDropStmt &stmt) {
7 auto result = make_uniq<DropStatement>();
8 auto &info = *result->info.get();
9 if (stmt.objects->length != 1) {
10 throw NotImplementedException("Can only drop one object at a time");
11 }
12 switch (stmt.removeType) {
13 case duckdb_libpgquery::PG_OBJECT_TABLE:
14 info.type = CatalogType::TABLE_ENTRY;
15 break;
16 case duckdb_libpgquery::PG_OBJECT_SCHEMA:
17 info.type = CatalogType::SCHEMA_ENTRY;
18 break;
19 case duckdb_libpgquery::PG_OBJECT_INDEX:
20 info.type = CatalogType::INDEX_ENTRY;
21 break;
22 case duckdb_libpgquery::PG_OBJECT_VIEW:
23 info.type = CatalogType::VIEW_ENTRY;
24 break;
25 case duckdb_libpgquery::PG_OBJECT_SEQUENCE:
26 info.type = CatalogType::SEQUENCE_ENTRY;
27 break;
28 case duckdb_libpgquery::PG_OBJECT_FUNCTION:
29 info.type = CatalogType::MACRO_ENTRY;
30 break;
31 case duckdb_libpgquery::PG_OBJECT_TABLE_MACRO:
32 info.type = CatalogType::TABLE_MACRO_ENTRY;
33 break;
34 case duckdb_libpgquery::PG_OBJECT_TYPE:
35 info.type = CatalogType::TYPE_ENTRY;
36 break;
37 default:
38 throw NotImplementedException("Cannot drop this type yet");
39 }
40
41 switch (stmt.removeType) {
42 case duckdb_libpgquery::PG_OBJECT_TYPE: {
43 auto view_list = PGPointerCast<duckdb_libpgquery::PGList>(ptr: stmt.objects);
44 auto target = PGPointerCast<duckdb_libpgquery::PGTypeName>(ptr: view_list->head->data.ptr_value);
45 info.name = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: target->names->tail->data.ptr_value)->val.str;
46 break;
47 }
48 case duckdb_libpgquery::PG_OBJECT_SCHEMA: {
49 auto view_list = PGPointerCast<duckdb_libpgquery::PGList>(ptr: stmt.objects->head->data.ptr_value);
50 if (view_list->length == 2) {
51 info.catalog = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->data.ptr_value)->val.str;
52 info.name = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->next->data.ptr_value)->val.str;
53 } else if (view_list->length == 1) {
54 info.name = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->data.ptr_value)->val.str;
55 } else {
56 throw ParserException("Expected \"catalog.schema\" or \"schema\"");
57 }
58 break;
59 }
60 default: {
61 auto view_list = PGPointerCast<duckdb_libpgquery::PGList>(ptr: stmt.objects->head->data.ptr_value);
62 if (view_list->length == 3) {
63 info.catalog = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->data.ptr_value)->val.str;
64 info.schema = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->next->data.ptr_value)->val.str;
65 info.name = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->next->next->data.ptr_value)->val.str;
66 } else if (view_list->length == 2) {
67 info.schema = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->data.ptr_value)->val.str;
68 info.name = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->next->data.ptr_value)->val.str;
69 } else if (view_list->length == 1) {
70 info.name = PGPointerCast<duckdb_libpgquery::PGValue>(ptr: view_list->head->data.ptr_value)->val.str;
71 } else {
72 throw ParserException("Expected \"catalog.schema.name\", \"schema.name\"or \"name\"");
73 }
74 break;
75 }
76 }
77 info.cascade = stmt.behavior == duckdb_libpgquery::PGDropBehavior::PG_DROP_CASCADE;
78 info.if_not_found = TransformOnEntryNotFound(missing_ok: stmt.missing_ok);
79 return std::move(result);
80}
81
82} // namespace duckdb
83