1#include "duckdb/parser/statement/set_statement.hpp"
2
3#include "duckdb/parser/transformer.hpp"
4#include "duckdb/parser/expression/constant_expression.hpp"
5
6namespace duckdb {
7
8namespace {
9
10SetScope ToSetScope(duckdb_libpgquery::VariableSetScope pg_scope) {
11 switch (pg_scope) {
12 case duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_LOCAL:
13 return SetScope::LOCAL;
14 case duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_SESSION:
15 return SetScope::SESSION;
16 case duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_GLOBAL:
17 return SetScope::GLOBAL;
18 case duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_DEFAULT:
19 return SetScope::AUTOMATIC;
20 default:
21 throw InternalException("Unexpected pg_scope: %d", pg_scope);
22 }
23}
24
25SetType ToSetType(duckdb_libpgquery::VariableSetKind pg_kind) {
26 switch (pg_kind) {
27 case duckdb_libpgquery::VariableSetKind::VAR_SET_VALUE:
28 return SetType::SET;
29 case duckdb_libpgquery::VariableSetKind::VAR_RESET:
30 return SetType::RESET;
31 default:
32 throw NotImplementedException("Can only SET or RESET a variable");
33 }
34}
35
36} // namespace
37
38unique_ptr<SetStatement> Transformer::TransformSetVariable(duckdb_libpgquery::PGVariableSetStmt &stmt) {
39 D_ASSERT(stmt.kind == duckdb_libpgquery::VariableSetKind::VAR_SET_VALUE);
40
41 if (stmt.scope == duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_LOCAL) {
42 throw NotImplementedException("SET LOCAL is not implemented.");
43 }
44
45 auto name = std::string(stmt.name);
46 D_ASSERT(!name.empty()); // parser protect us!
47 if (stmt.args->length != 1) {
48 throw ParserException("SET needs a single scalar value parameter");
49 }
50 D_ASSERT(stmt.args->head && stmt.args->head->data.ptr_value);
51 auto const_val = PGPointerCast<duckdb_libpgquery::PGAConst>(ptr: stmt.args->head->data.ptr_value);
52 D_ASSERT(const_val->type == duckdb_libpgquery::T_PGAConst);
53
54 auto value = TransformValue(val: const_val->val)->value;
55 return make_uniq<SetVariableStatement>(args&: name, args&: value, args: ToSetScope(pg_scope: stmt.scope));
56}
57
58unique_ptr<SetStatement> Transformer::TransformResetVariable(duckdb_libpgquery::PGVariableSetStmt &stmt) {
59 D_ASSERT(stmt.kind == duckdb_libpgquery::VariableSetKind::VAR_RESET);
60
61 if (stmt.scope == duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_LOCAL) {
62 throw NotImplementedException("RESET LOCAL is not implemented.");
63 }
64
65 auto name = std::string(stmt.name);
66 D_ASSERT(!name.empty()); // parser protect us!
67
68 return make_uniq<ResetVariableStatement>(args&: name, args: ToSetScope(pg_scope: stmt.scope));
69}
70
71unique_ptr<SetStatement> Transformer::TransformSet(duckdb_libpgquery::PGVariableSetStmt &stmt) {
72 D_ASSERT(stmt.type == duckdb_libpgquery::T_PGVariableSetStmt);
73
74 SetType set_type = ToSetType(pg_kind: stmt.kind);
75
76 switch (set_type) {
77 case SetType::SET:
78 return TransformSetVariable(stmt);
79 case SetType::RESET:
80 return TransformResetVariable(stmt);
81 default:
82 throw NotImplementedException("Type not implemented for SetType");
83 }
84}
85
86} // namespace duckdb
87