1 /*
2 * Copyright (c) 2015, 2021, Oracle and/or its affiliates.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2.0,
6 * as published by the Free Software Foundation.
7 *
8 * This program is also distributed with certain software (including
9 * but not limited to OpenSSL) that is licensed under separate terms,
10 * as designated in a particular file or component or in included license
11 * documentation. The authors of MySQL hereby grant you an additional
12 * permission to link the program and your derivative works with the
13 * separately licensed software that they have included with MySQL.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License, version 2.0, for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "view_statement_builder.h"
26 #include "ngs_common/protocol_protobuf.h"
27 #include "xpl_error.h"
28
29 namespace xpl {
30
31 template <typename M>
build_common(const M & msg) const32 void View_statement_builder::build_common(const M &msg) const {
33 if (!msg.has_stmt())
34 throw ngs::Error_code(ER_X_INVALID_ARGUMENT, "The field that defines the select statement is required");
35
36 if (msg.has_algorithm()) add_algorithm(msg.algorithm());
37 if (msg.has_definer()) add_definer(msg.definer());
38 if (msg.has_security()) add_sql_security(msg.security());
39 m_builder.put("VIEW ");
40 add_collection(msg.collection());
41 if (msg.column_size() > 0) add_columns(msg.column());
42 m_builder.put(" AS ");
43 add_stmt(msg.stmt());
44 if (msg.has_check()) add_check_option(msg.check());
45 }
46
build(const View_create & msg) const47 void View_statement_builder::build(const View_create &msg) const {
48 m_builder.put("CREATE ");
49 if (msg.has_replace_existing() && msg.replace_existing())
50 m_builder.put("OR REPLACE ");
51 build_common(msg);
52 }
53
build(const View_modify & msg) const54 void View_statement_builder::build(const View_modify &msg) const {
55 m_builder.put("ALTER ");
56 build_common(msg);
57 }
58
build(const View_drop & msg) const59 void View_statement_builder::build(const View_drop &msg) const {
60 m_builder.put("DROP VIEW ");
61 if (msg.has_if_exists() && msg.if_exists())
62 m_builder.put("IF EXISTS ");
63 add_collection(msg.collection());
64 }
65
add_definer(const std::string & definer) const66 void View_statement_builder::add_definer(const std::string &definer) const {
67 if (definer.empty()) return;
68
69 m_builder.put("DEFINER=");
70 std::string::size_type p = definer.find("@");
71 if (p == std::string::npos)
72 m_builder.put_quote(definer).put(" ");
73 else
74 m_builder.put_quote(definer.substr(0, p))
75 .put("@")
76 .put_quote(definer.substr(p + 1))
77 .put(" ");
78 }
79
add_algorithm(const Algorithm & algorithm) const80 void View_statement_builder::add_algorithm(const Algorithm &algorithm) const {
81 m_builder.put("ALGORITHM=");
82 switch (algorithm) {
83 case Mysqlx::Crud::UNDEFINED:
84 m_builder.put("UNDEFINED ");
85 break;
86
87 case Mysqlx::Crud::MERGE:
88 m_builder.put("MERGE ");
89 break;
90
91 case Mysqlx::Crud::TEMPTABLE:
92 m_builder.put("TEMPTABLE ");
93 break;
94
95 default:
96 assert("Unknown ALGORITHM type");
97 }
98 }
99
add_sql_security(const Sql_security & security) const100 void View_statement_builder::add_sql_security(const Sql_security &security)
101 const {
102 m_builder.put("SQL SECURITY ");
103 switch (security) {
104 case Mysqlx::Crud::DEFINER:
105 m_builder.put("DEFINER ");
106 break;
107
108 case Mysqlx::Crud::INVOKER:
109 m_builder.put("INVOKER ");
110 break;
111
112 default:
113 assert("Unknown SECURITY type");
114 }
115 }
116
add_check_option(const Check_option & option) const117 void View_statement_builder::add_check_option(const Check_option &option)
118 const {
119 m_builder.put(" WITH ");
120
121 switch (option) {
122 case Mysqlx::Crud::CASCADED:
123 m_builder.put("CASCADED");
124 break;
125
126 case Mysqlx::Crud::LOCAL:
127 m_builder.put("LOCAL");
128 break;
129
130 default:
131 assert("Unknown CHECK type");
132 }
133 m_builder.put(" CHECK OPTION");
134 }
135
add_columns(const Column_list & columns) const136 void View_statement_builder::add_columns(const Column_list &columns) const {
137 m_builder.put(" (").put_list(columns, &Generator::put_identifier).put(")");
138 }
139
add_stmt(const Find & find) const140 void View_statement_builder::add_stmt(const Find &find) const {
141 Expression_generator gen(m_builder.m_qb, find.args(),
142 find.collection().schema(),
143 is_table_data_model(find));
144 Find_statement_builder(gen).build(find);
145 }
146 } // namespace xpl
147