1#include "duckdb/parser/expression/columnref_expression.hpp"
2#include "duckdb/parser/statement/create_statement.hpp"
3#include "duckdb/parser/parsed_data/create_index_info.hpp"
4#include "duckdb/parser/tableref/basetableref.hpp"
5#include "duckdb/parser/transformer.hpp"
6#include "duckdb/common/string_util.hpp"
7
8using namespace duckdb;
9using namespace std;
10
11static IndexType StringToIndexType(const string &str) {
12 string upper_str = StringUtil::Upper(str);
13 if (upper_str == "INVALID") {
14 return IndexType::INVALID;
15 } else if (upper_str == "ART") {
16 return IndexType::ART;
17 } else {
18 throw ConversionException(StringUtil::Format("No IndexType conversion from string '%s'", upper_str.c_str()));
19 }
20 return IndexType::INVALID;
21}
22
23unique_ptr<CreateStatement> Transformer::TransformCreateIndex(PGNode *node) {
24 auto stmt = reinterpret_cast<PGIndexStmt *>(node);
25 assert(stmt);
26 auto result = make_unique<CreateStatement>();
27 auto info = make_unique<CreateIndexInfo>();
28
29 info->unique = stmt->unique;
30 info->on_conflict = stmt->if_not_exists ? OnCreateConflict::IGNORE : OnCreateConflict::ERROR;
31
32 for (auto cell = stmt->indexParams->head; cell != nullptr; cell = cell->next) {
33 auto index_element = (PGIndexElem *)cell->data.ptr_value;
34 if (index_element->collation) {
35 throw NotImplementedException("Index with collation not supported yet!");
36 }
37 if (index_element->opclass) {
38 throw NotImplementedException("Index with opclass not supported yet!");
39 }
40
41 if (index_element->name) {
42 // create a column reference expression
43 info->expressions.push_back(make_unique<ColumnRefExpression>(index_element->name, stmt->relation->relname));
44 } else {
45 // parse the index expression
46 assert(index_element->expr);
47 info->expressions.push_back(TransformExpression(index_element->expr));
48 }
49 }
50
51 info->index_type = StringToIndexType(string(stmt->accessMethod));
52 auto tableref = make_unique<BaseTableRef>();
53 tableref->table_name = stmt->relation->relname;
54 if (stmt->relation->schemaname) {
55 tableref->schema_name = stmt->relation->schemaname;
56 }
57 info->table = move(tableref);
58 if (stmt->idxname) {
59 info->index_name = stmt->idxname;
60 } else {
61 throw NotImplementedException("Index wout a name not supported yet!");
62 }
63 result->info = move(info);
64 return result;
65}
66