Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit e3ac1ba

Browse files
committed
Ported not-null foreign keys and short-circuiting
1 parent 5caae6d commit e3ac1ba

File tree

8 files changed

+598
-1
lines changed

8 files changed

+598
-1
lines changed

src/binder/bind_node_visitor.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "binder/bind_node_visitor.h"
1414
#include "catalog/catalog.h"
15+
#include "catalog/table_catalog.h"
16+
#include "catalog/column_catalog.h"
1517
#include "expression/expression_util.h"
1618
#include "expression/star_expression.h"
1719
#include "type/type_id.h"
@@ -250,6 +252,21 @@ void BindNodeVisitor::Visit(expression::TupleValueExpression *expr) {
250252
expr->SetColName(col_name);
251253
expr->SetValueType(value_type);
252254
expr->SetBoundOid(col_pos_tuple);
255+
256+
// TODO(esargent): Uncommenting the following code makes AddressSanitizer get mad at me with a
257+
// heap buffer overflow whenever I try a query that references the same non-null attribute multiple
258+
// times (e.g. 'SELECT id FROM t WHERE id < 3 AND id > 1'). Leaving it commented out prevents the
259+
// memory error, but then this prevents the is_not_null flag of a tuple expression from being
260+
// populated in some cases (specifically, when the expression's table name is initially empty).
261+
262+
//if (table_obj == nullptr) {
263+
// LOG_DEBUG("Extracting regular table object");
264+
// BinderContext::GetRegularTableObj(context_, table_name, table_obj, depth);
265+
//}
266+
267+
if (table_obj != nullptr) {
268+
expr->SetIsNotNull(table_obj->GetColumnCatalogEntry(std::get<2>(col_pos_tuple), false)->IsNotNull());
269+
}
253270
}
254271
}
255272

src/include/common/internal_types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,14 @@ enum class RuleType : uint32_t {
13931393
TV_EQUALITY_WITH_TWO_CV, // (A.B = x) AND (A.B = y) where x/y are constant
13941394
TRANSITIVE_CLOSURE_CONSTANT, // (A.B = x) AND (A.B = C.D)
13951395

1396+
// Boolean short-circuit rules
1397+
AND_SHORT_CIRCUIT, // (FALSE AND B)
1398+
OR_SHORT_CIRCUIT, // (TRUE OR B)
1399+
1400+
// Catalog-based NULL/NON-NULL rules
1401+
NULL_LOOKUP_ON_NOT_NULL_COLUMN,
1402+
NOT_NULL_LOOKUP_ON_NOT_NULL_COLUMN,
1403+
13961404
// Place holder to generate number of rules compile time
13971405
NUM_RULES
13981406

src/include/expression/tuple_value_expression.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class TupleValueExpression : public AbstractExpression {
7979
tuple_idx_ = tuple_idx;
8080
}
8181

82+
inline void SetIsNotNull(bool is_not_null) {
83+
is_not_null_ = is_not_null;
84+
}
85+
8286
/**
8387
* @brief Attribute binding
8488
* @param binding_contexts
@@ -116,6 +120,8 @@ class TupleValueExpression : public AbstractExpression {
116120
if ((table_name_.empty() xor other.table_name_.empty()) ||
117121
col_name_.empty() xor other.col_name_.empty())
118122
return false;
123+
if (GetIsNotNull() != other.GetIsNotNull())
124+
return false;
119125
bool res = bound_obj_id_ == other.bound_obj_id_;
120126
if (!table_name_.empty() && !other.table_name_.empty())
121127
res = table_name_ == other.table_name_ && res;
@@ -151,6 +157,8 @@ class TupleValueExpression : public AbstractExpression {
151157

152158
bool GetIsBound() const { return is_bound_; }
153159

160+
bool GetIsNotNull() const { return is_not_null_; }
161+
154162
const std::tuple<oid_t, oid_t, oid_t> &GetBoundOid() const {
155163
return bound_obj_id_;
156164
}
@@ -185,7 +193,8 @@ class TupleValueExpression : public AbstractExpression {
185193
value_idx_(other.value_idx_),
186194
tuple_idx_(other.tuple_idx_),
187195
table_name_(other.table_name_),
188-
col_name_(other.col_name_) {}
196+
col_name_(other.col_name_),
197+
is_not_null_(other.is_not_null_) {}
189198

190199
// Bound flag
191200
bool is_bound_ = false;
@@ -196,6 +205,7 @@ class TupleValueExpression : public AbstractExpression {
196205
int tuple_idx_;
197206
std::string table_name_;
198207
std::string col_name_;
208+
bool is_not_null_ = false;
199209

200210
const planner::AttributeInfo *ai_;
201211
};

src/include/optimizer/rule_rewrite.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
namespace peloton {
2121
namespace optimizer {
2222

23+
using GroupExprTemplate = GroupExpression;
24+
using OptimizeContext = OptimizeContext;
25+
2326
/* Rules are applied from high to low priority */
2427
enum class RulePriority : int {
2528
HIGH = 3,
@@ -71,5 +74,49 @@ class TransitiveClosureConstantTransform: public Rule {
7174
OptimizeContext *context) const override;
7275
};
7376

77+
class AndShortCircuit: public Rule {
78+
public:
79+
AndShortCircuit();
80+
81+
int Promise(GroupExprTemplate *group_expr, OptimizeContext *context) const override;
82+
bool Check(std::shared_ptr<AbstractNodeExpression> plan, OptimizeContext *context) const override;
83+
void Transform(std::shared_ptr<AbstractNodeExpression> input,
84+
std::vector<std::shared_ptr<AbstractNodeExpression>> &transformed,
85+
OptimizeContext *context) const override;
86+
};
87+
88+
class OrShortCircuit: public Rule {
89+
public:
90+
OrShortCircuit();
91+
92+
int Promise(GroupExprTemplate *group_expr, OptimizeContext *context) const override;
93+
bool Check(std::shared_ptr<AbstractNodeExpression> plan, OptimizeContext *context) const override;
94+
void Transform(std::shared_ptr<AbstractNodeExpression> input,
95+
std::vector<std::shared_ptr<AbstractNodeExpression>> &transformed,
96+
OptimizeContext *context) const override;
97+
};
98+
99+
class NullLookupOnNotNullColumn: public Rule {
100+
public:
101+
NullLookupOnNotNullColumn();
102+
103+
int Promise(GroupExprTemplate *group_expr, OptimizeContext *context) const override;
104+
bool Check(std::shared_ptr<AbstractNodeExpression> plan, OptimizeContext *context) const override;
105+
void Transform(std::shared_ptr<AbstractNodeExpression> input,
106+
std::vector<std::shared_ptr<AbstractNodeExpression>> &transformed,
107+
OptimizeContext *context) const override;
108+
};
109+
110+
class NotNullLookupOnNotNullColumn: public Rule {
111+
public:
112+
NotNullLookupOnNotNullColumn();
113+
114+
int Promise(GroupExprTemplate *group_expr, OptimizeContext *context) const override;
115+
bool Check(std::shared_ptr<AbstractNodeExpression> plan, OptimizeContext *context) const override;
116+
void Transform(std::shared_ptr<AbstractNodeExpression> input,
117+
std::vector<std::shared_ptr<AbstractNodeExpression>> &transformed,
118+
OptimizeContext *context) const override;
119+
};
120+
74121
} // namespace optimizer
75122
} // namespace peloton

src/optimizer/binding.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212

1313
#include "optimizer/binding.h"
1414

15+
#include <memory>
16+
1517
#include "common/logger.h"
1618
#include "optimizer/operator_visitor.h"
1719
#include "optimizer/optimizer.h"
1820
#include "optimizer/absexpr_expression.h"
1921
#include "expression/group_marker_expression.h"
22+
#include "expression/abstract_expression.h"
23+
#include "expression/tuple_value_expression.h"
2024

2125
namespace peloton {
2226
namespace optimizer {

src/optimizer/rule.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,15 @@ RuleSet::RuleSet() {
7676
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new TVEqualityWithTwoCVTransform());
7777
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new TransitiveClosureConstantTransform());
7878

79+
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new AndShortCircuit());
80+
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new OrShortCircuit());
81+
82+
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new NullLookupOnNotNullColumn());
83+
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new NotNullLookupOnNotNullColumn());
84+
85+
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new TVEqualityWithTwoCVTransform());
86+
AddRewriteRule(RewriteRuleSetName::GENERIC_RULES, new TransitiveClosureConstantTransform());
87+
7988
// Define transformation/implementation rules
8089
AddTransformationRule(new InnerJoinCommutativity());
8190
AddTransformationRule(new InnerJoinAssociativity());

0 commit comments

Comments
 (0)