/Users/deen/code/yugabyte-db/src/yb/docdb/doc_pg_expr.h
Line | Count | Source |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_DOCDB_DOC_PG_EXPR_H_ |
15 | | #define YB_DOCDB_DOC_PG_EXPR_H_ |
16 | | |
17 | | #include "yb/common/ql_expr.h" |
18 | | #include "yb/common/pgsql_protocol.pb.h" |
19 | | #include "yb/common/schema.h" |
20 | | #include "yb/util/status.h" |
21 | | |
22 | | namespace yb { |
23 | | namespace docdb { |
24 | | |
25 | | // DocPgExprExecutor is optimized for repeatable execution of serialized postgres expressions. |
26 | | // |
27 | | // Evaluations are supposed to happen in context of single relation scan, and expected |
28 | | // DocPgExprExecutor object's lifespan is the duration of that scan. It is also can be used to |
29 | | // evaluate expressions for a single row operation, such as insert or update. |
30 | | // Constructor takes relation's schema as a parameter, it is needed to extract column values |
31 | | // referenced by the expressions and convert to Postgres format they expect. |
32 | | // |
33 | | // After object has been constructed, the expressions and column references should be added, in |
34 | | // any order. Column references, where clause and target expressions are treated differently and |
35 | | // added using different methods. All parts are optional, however if any expression refers a column |
36 | | // (has a Var expression node in the tree), it must be explicitly added. |
37 | | // |
38 | | // Then Exec method should be called to evaluate expressions per relation row. After Exec was called |
39 | | // for the first time, column references or expressions can no longer be added to the executor. |
40 | | class DocPgExprExecutor { |
41 | | public: |
42 | | // Create new executor to evaluate expressions for a relation with specified schema. |
43 | 4.16M | explicit DocPgExprExecutor(const Schema *schema) : schema_(schema) {} |
44 | | |
45 | | // Destroy the executor and release all allocated resources. |
46 | 4.16M | virtual ~DocPgExprExecutor() {} |
47 | | |
48 | | // Add column reference to the executor. |
49 | | // Column id, attribute number, type information is extracted from the protobuf element and |
50 | | // stored in a data structure allowing to quickly locate the value in the row, convert it from |
51 | | // DocDB data format to Postgres and then locate it by attribute number when evaluating |
52 | | // expressions. |
53 | | CHECKED_STATUS AddColumnRef(const PgsqlColRefPB& column_ref); |
54 | | |
55 | | // Add a where clause expression to the executor. |
56 | | // Expression is deserialized and stored in the list of where clause expressions. |
57 | | // Where clause expression must return boolean value. Where clause expressions are implicitly |
58 | | // AND'ed. If any is evaluated to false, no further evaluation happens and row is considered |
59 | | // filtered out. Empty where clause means no rows filtered out. |
60 | | CHECKED_STATUS AddWhereExpression(const PgsqlExpressionPB& ql_expr); |
61 | | |
62 | | // Add a target expression to the executor. |
63 | | // Expression is deserialized and stored in the list of the target expressions. Function prepares |
64 | | // to convert evaluation results to DocDB format based on expression's Postgres data type. |
65 | | // Each expression produces single value to be returned to client (like in SELECT), stored to |
66 | | // DocDB table (like in UPDATE), or both (like in UPDATE with RETURNING clause). Target |
67 | | // expressions are evaluated unless where clause was evaluated to false. |
68 | | CHECKED_STATUS AddTargetExpression(const PgsqlExpressionPB& ql_expr); |
69 | | |
70 | | // Evaluate the expression in the context of single row. |
71 | | // The results vector is expected to have at least as many entries as the number of target |
72 | | // expressions added to the executor. If no target expressions were added it is OK to pass null. |
73 | | // The match parameter is mandatory. It returns true if the where clause is empty or evaluated to |
74 | | // true, false otherwise. If function returns false it does not modify the results. |
75 | | // Method extracts values from the row according to the column references added to the executor. |
76 | | // Extracted values are converted to Postgres format (datum and is_null pairs). The case if no |
77 | | // columns are referenced is possible, but not very practical, it means that all expressions are |
78 | | // constants. |
79 | | // Then where clause expressions are evaluated, if any, in the order they are added. If a where |
80 | | // clause expression is evaluated to false, execution stops and match is returned as false. |
81 | | // Then target expressions are evaluated in the order they are added. Execution results are |
82 | | // converted to DocDB values and written into the next element of the results vector. This is a |
83 | | // caller's responsibility to track target expressions added to the executor, provide sufficiently |
84 | | // long results vector and match the results. |
85 | | CHECKED_STATUS Exec(const QLTableRow& table_row, |
86 | | std::vector<QLExprResult>* results, |
87 | | bool* match); |
88 | | |
89 | | private: |
90 | | // The relation schema |
91 | | const Schema *schema_; |
92 | | // Private object hides implementation details, heavily based on the ybgate. |
93 | | // We do not want ybgate data types and functions to appear in this header file, and therefore |
94 | | // included everywhere where we may want to use the executor. |
95 | | class Private; |
96 | | // The Private object's size is not known here, so explicit deleter is needed. |
97 | | // The implementation in the .cc file has all the information compiler needs. |
98 | | struct private_deleter { void operator()(Private*) const; }; |
99 | | std::unique_ptr<Private, private_deleter> private_; |
100 | | }; |
101 | | |
102 | | } // namespace docdb |
103 | | } // namespace yb |
104 | | |
105 | | |
106 | | #endif // YB_DOCDB_DOC_PG_EXPR_H_ |