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
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26 #ifndef _XPL_EXPR_GENERATOR_H_
27 #define _XPL_EXPR_GENERATOR_H_
28
29 #include "query_string_builder.h"
30 #include "ngs_common/protocol_protobuf.h"
31 #include <stdexcept>
32
33
34 namespace xpl
35 {
36
37 class Expression_generator
38 {
39 public:
40 typedef ::Mysqlx::Expr::Expr Expr;
41 typedef ::google::protobuf::RepeatedPtrField< ::Mysqlx::Datatypes::Scalar > Args;
42
43 class Error : public std::invalid_argument
44 {
45 int m_error;
46 public:
47 Error(int error_code, const std::string& message);
48
error()49 int error() const { return m_error; }
50 };
51
52 // source: ``Mysqlx.Resultset.ColumnMetadata`` for list of known values
53 enum Octets_content_type
54 {
55 CT_PLAIN = 0x0000, // default value; general use of octets
56 CT_GEOMETRY = 0x0001, // BYTES 0x0001 GEOMETRY (WKB encoding)
57 CT_JSON = 0x0002, // BYTES 0x0002 JSON (text encoding)
58 CT_XML = 0x0003 // BYTES 0x0003 XML (text encoding)
59 };
60
Expression_generator(Query_string_builder & qb,const Args & args,const std::string & default_schema,const bool & is_relational)61 Expression_generator(Query_string_builder &qb, const Args &args, const std::string &default_schema, const bool &is_relational)
62 : m_qb(qb), m_args(args), m_default_schema(default_schema), m_is_relational(is_relational)
63 {}
64
65 template<typename T>
feed(const T & expr)66 inline void feed(const T &expr) const { generate(expr); }
67
68 Expression_generator clone(Query_string_builder &qb) const;
query_string_builder()69 Query_string_builder &query_string_builder() const { return m_qb; }
70
71 private:
72 typedef ::google::protobuf::RepeatedPtrField< ::Mysqlx::Expr::DocumentPathItem > Document_path;
73 typedef ::google::protobuf::uint32 Placeholder;
74
75 void generate(const Mysqlx::Expr::Expr &arg) const;
76 void generate(const Mysqlx::Expr::Identifier &arg, const bool is_function=false) const;
77 void generate(const Mysqlx::Expr::ColumnIdentifier &arg) const;
78 void generate(const Mysqlx::Expr::FunctionCall &arg) const;
79 void generate(const Mysqlx::Expr::Operator &arg) const;
80 void generate(const Mysqlx::Datatypes::Any &arg) const;
81 void generate(const Mysqlx::Datatypes::Scalar &arg) const;
82 void generate(const Mysqlx::Datatypes::Scalar::Octets &arg) const;
83 void generate(const Document_path &arg) const;
84 void generate(const Placeholder &arg) const;
85 void generate(const Mysqlx::Expr::Object &arg) const;
86 void generate(const Mysqlx::Expr::Object::ObjectField &arg) const;
87 void generate(const Mysqlx::Expr::Array &arg) const;
88
89 template <typename T>
90 void generate_for_each(const ::google::protobuf::RepeatedPtrField<T> &list,
91 void (Expression_generator::*generate_fun)(const T&) const,
92 const typename ::google::protobuf::RepeatedPtrField<T>::size_type offset = 0) const;
93 void generate_unquote_param(const Mysqlx::Expr::Expr &arg) const;
94
95 void binary_operator(const Mysqlx::Expr::Operator &arg, const char* str) const;
96 void unary_operator(const Mysqlx::Expr::Operator &arg, const char* str) const;
97 void nullary_operator(const Mysqlx::Expr::Operator &arg, const char* str) const;
98 void in_expression(const Mysqlx::Expr::Operator &arg, const char* str) const;
99 void like_expression(const Mysqlx::Expr::Operator &arg, const char* str) const;
100 void between_expression(const Mysqlx::Expr::Operator &arg, const char* str) const;
101 void date_expression(const Mysqlx::Expr::Operator &arg, const char* str) const;
102 void cast_expression(const Mysqlx::Expr::Operator &arg) const;
103 void binary_expression(const Mysqlx::Expr::Operator &arg, const char* str) const;
104 void asterisk_operator(const Mysqlx::Expr::Operator &arg) const;
105
106 Query_string_builder &m_qb;
107 const Args &m_args;
108 const std::string &m_default_schema;
109 const bool &m_is_relational;
110 };
111
112
113 template<typename T>
generate_expression(Query_string_builder & qb,const T & expr,const Expression_generator::Args & args,const std::string & default_schema,bool is_relational)114 void generate_expression(Query_string_builder &qb, const T &expr,
115 const Expression_generator::Args &args,
116 const std::string &default_schema,
117 bool is_relational)
118 {
119 Expression_generator gen(qb, args, default_schema, is_relational);
120 gen.feed(expr);
121 }
122
123
124 template<typename T>
generate_expression(const T & expr,const Expression_generator::Args & args,const std::string & default_schema,bool is_relational)125 ngs::PFS_string generate_expression(const T &expr,
126 const Expression_generator::Args &args,
127 const std::string &default_schema,
128 bool is_relational)
129 {
130 Query_string_builder qb;
131 generate_expression(qb, expr, args, default_schema, is_relational);
132 return qb.get();
133 }
134
135
136 template<typename T>
generate_expression(Query_string_builder & qb,const T & expr,const std::string & default_schema,bool is_relational)137 void generate_expression(Query_string_builder &qb, const T &expr, const std::string &default_schema, bool is_relational)
138 {
139 generate_expression(qb, expr, Expression_generator::Args(), default_schema, is_relational);
140 }
141
142
143 template<typename T>
generate_expression(const T & expr,const std::string & default_schema,bool is_relational)144 ngs::PFS_string generate_expression(const T &expr, const std::string &default_schema, bool is_relational)
145 {
146 return generate_expression(expr, Expression_generator::Args(), default_schema, is_relational);
147 }
148
149 } // namespace xpl
150
151 #endif // _XPL_EXPR_GENERATOR_H_
152