Skip to content

Commit 82e5bf5

Browse files
oerlingmeta-codesync[bot]
authored andcommitted
Track Value constraints through plan construction (facebookincubator#708)
Summary: Pull Request resolved: facebookincubator#708 Differential Revision: D89130357
1 parent 5302844 commit 82e5bf5

23 files changed

+1125
-141
lines changed

axiom/optimizer/Filters.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,32 @@ float combineSelectivities(
127127
}
128128

129129
const Value& value(const PlanState& state, ExprCP expr) {
130+
auto it = state.constraints.find(expr->id());
131+
if (it != state.constraints.end()) {
132+
return it->second;
133+
}
130134
return expr->value();
131135
}
132136

137+
void addConstraint(int32_t exprId, Value value, ConstraintMap& constraints) {
138+
// Limit cardinality based on type kind
139+
auto typeKind = value.type->kind();
140+
141+
if (typeKind == velox::TypeKind::BOOLEAN) {
142+
// Boolean can have at most 2 distinct values (true/false)
143+
value.cardinality = std::min(value.cardinality, 2.0f);
144+
} else if (typeKind == velox::TypeKind::TINYINT) {
145+
// TINYINT (int8) can have at most 256 distinct values (-128 to 127)
146+
value.cardinality = std::min(value.cardinality, 256.0f);
147+
} else if (typeKind == velox::TypeKind::SMALLINT) {
148+
// SMALLINT (int16) can have at most 65536 distinct values
149+
value.cardinality = std::min(value.cardinality, 65536.0f);
150+
}
151+
// Other types (INTEGER, BIGINT, VARCHAR, etc.) have no practical limit
152+
153+
constraints.insert_or_assign(exprId, value);
154+
}
155+
133156
Selectivity comparisonSelectivity(
134157
const PlanState& state,
135158
ExprCP expr,
@@ -216,10 +239,15 @@ Selectivity functionSelectivity(
216239
}
217240

218241
Selectivity conjunctsSelectivity(
219-
const PlanState& state,
242+
PlanState& state,
220243
std::span<const ExprCP> conjuncts,
221244
bool updateConstraints,
222245
ConstraintMap& newConstraints) {
246+
// Update constraints for each conjunct before processing
247+
for (auto* conjunct : conjuncts) {
248+
exprConstraint(conjunct, state, true);
249+
}
250+
223251
std::vector<Selectivity> selectivities;
224252
selectivities.reserve(conjuncts.size());
225253

@@ -271,7 +299,7 @@ Selectivity conjunctsSelectivity(
271299
}
272300

273301
Selectivity exprSelectivity(
274-
const PlanState& state,
302+
PlanState& state,
275303
ExprCP expr,
276304
bool updateConstraints,
277305
ConstraintMap& newConstraints) {
@@ -1313,4 +1341,20 @@ Selectivity rangeSelectivity(
13131341
return {0.5 * (1.0 - nullFrac), nullFrac};
13141342
}
13151343

1344+
/// Declared in namespace to allow calling from debugger.
1345+
std::string constraintsString(ConstraintMap& constraints) {
1346+
std::stringstream out;
1347+
for (const auto& pair : constraints) {
1348+
out << pair.first;
1349+
if (queryCtx() != nullptr) {
1350+
auto* expr = queryCtx()->objectAt(pair.first);
1351+
if (expr != nullptr) {
1352+
out << " (" << expr->toString() << ")";
1353+
}
1354+
}
1355+
out << " = " << pair.second.toString() << "\n";
1356+
}
1357+
return out.str();
1358+
}
1359+
13161360
} // namespace facebook::axiom::optimizer

axiom/optimizer/Filters.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ float combineSelectivities(
4343

4444
const Value& value(const PlanState& state, ExprCP expr);
4545

46+
/// Adds a constraint to the constraint map with cardinality limited by type.
47+
/// For BOOLEAN: max 2, TINYINT: max 256, SMALLINT: max 65536.
48+
void addConstraint(int32_t exprId, Value value, ConstraintMap& constraints);
49+
4650
Selectivity columnComparisonSelectivity(
4751
ExprCP left,
4852
ExprCP right,
@@ -53,13 +57,13 @@ Selectivity columnComparisonSelectivity(
5357
ConstraintMap& constraints);
5458

5559
Selectivity exprSelectivity(
56-
const PlanState& state,
60+
PlanState& state,
5761
ExprCP expr,
5862
bool updateConstraints,
5963
ConstraintMap& newConstraints);
6064

6165
Selectivity conjunctsSelectivity(
62-
const PlanState& state,
66+
PlanState& state,
6367
std::span<const ExprCP> conjuncts,
6468
bool updateConstraints,
6569
ConstraintMap& newConstraints);

axiom/optimizer/FunctionRegistry.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
namespace facebook::axiom::optimizer {
2222

23+
struct PlanState;
24+
struct Value;
25+
2326
/// A bit set that qualifies an Expr. Represents which functions/kinds
2427
/// of functions are found inside the children of an Expr.
2528
class FunctionSet {
@@ -182,6 +185,10 @@ struct FunctionMetadata {
182185
const logical_plan::CallExpr* call,
183186
std::vector<PathCP>& paths)>
184187
explode;
188+
189+
/// Function to compute derived constraints for function calls.
190+
std::function<std::optional<Value>(ExprCP, PlanState& state)>
191+
functionConstraint;
185192
};
186193

187194
using FunctionMetadataCP = const FunctionMetadata*;

axiom/optimizer/JoinSample.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,20 @@ std::shared_ptr<runner::Runner> prepareSampleRunner(
142142
make<Call>(toName(kHashMix), bigintValue(), hashes, FunctionSet{});
143143

144144
ColumnCP hashColumn = make<Column>(toName("hash"), nullptr, hash->value());
145+
146+
// Create temporary PlanState for Project and Filter constructors
147+
PlanState tempState(*queryCtx()->optimization(), nullptr);
148+
145149
RelationOpPtr project = make<Project>(
146-
scan, ExprVector{hash}, ColumnVector{hashColumn}, /*redundant=*/false);
150+
scan,
151+
ExprVector{hash},
152+
ColumnVector{hashColumn},
153+
/*redundant=*/false,
154+
tempState);
147155

148156
// (hash % mod) < lim
149157
ExprCP filterExpr = makeCall(
150158
kSample, velox::BOOLEAN(), hashColumn, bigintLit(mod), bigintLit(lim));
151-
152-
// Create temporary PlanState for Filter constructor
153-
PlanState tempState(*queryCtx()->optimization(), nullptr);
154159
RelationOpPtr filter =
155160
make<Filter>(tempState, project, ExprVector{filterExpr});
156161

0 commit comments

Comments
 (0)