Github user zellerh commented on a diff in the pull request:
https://github.com/apache/incubator-trafodion/pull/218#discussion_r47168057
--- Diff: core/sql/optimizer/GroupAttr.cpp ---
@@ -580,6 +612,127 @@ void
GroupAttributes::addSuitableCompRefOptConstraints(
} // loop over constraints
}
+// a const method for validating eliminated columns in a sort order,
+// usually called for validating an earlier result created with
+// the next method below, tryToEliminateOrderColumnBasedOnEqualsPred()
+NABoolean GroupAttributes::canEliminateOrderColumnBasedOnEqualsPred(
+ ValueId col) const
+{
+ // cast away const-ness and call the non-const method without
+ // predicates, which will mean it won't side-effect "this"
+ return const_cast<GroupAttributes *>(this)->
+ tryToEliminateOrderColumnBasedOnEqualsPred(col, NULL);
+}
+
+// This and the previous method are used to match required sort orders
+// or arrangements to an actual key ordering of a table, in cases
+// where some columns are equated to a constant, like this, with the
+// clustering key being (a,b,c)
+//
+// select ...
+// from t
+// where a = 5
+// order by b
+//
+// Note that for VEGs, this is handled differently (see
+// ValueIdList::satisfiesReqdOrder), this code is only for non-VEG
+// cases (usually computed columns, also varchar).
+//
+// If we eliminate a column based on a supplied predicate, then
+// this predicate is added as an Optimizer check constraint to the
+// group attributes, so that future calls will continue to accept
+// the simplified sort order.
+NABoolean GroupAttributes::tryToEliminateOrderColumnBasedOnEqualsPred(
+ ValueId col,
+ const ValueIdSet *preds)
+{
+ NABoolean result = FALSE;
+
+ if (preds || hasConstraintOfType(ITM_CHECK_OPT_CONSTRAINT))
+ {
+ // Comparison failed. If the caller provided predicates,
+ // then we can try something similar to what we did with
+ // group attributes above. If the predicate equate the
+ // column with a constant, then we can eliminate it as
+ // well. Note that we don't expect the requirements to
+ // omit such columns, since the parent will usually not
+ // know about such predicates, so we check this condition
+ // only after trying the regular method.
+ //
+ // This situation typically happens with computed columns
+ // where predicates are added after VEGs are formed
+
+ ValueIdSet checkConstraints;
+ ValueIdSet checkPreds;
+
+ // look for predicates we remembered from earlier calls
+ getConstraintsOfType(ITM_CHECK_OPT_CONSTRAINT,
+ checkConstraints);
+
+ for (ValueId c = checkConstraints.init();
+ checkConstraints.next(c);
+ checkConstraints.advance(c))
+ checkPreds += static_cast<CheckOptConstraint *>(
+ c.getItemExpr())->getCheckPreds();
+
+ // also use newly provided predicates
+ if (preds)
+ checkPreds += *preds;
+
+ // if the column is descending, then get rid of the Inverse
+ // operator for the next check
+ if (col.getItemExpr()->getOperatorType() == ITM_INVERSE)
+ col = col.getItemExpr()->child(0).getValueId();
+
+ // convert col from a VEGRef to a base column, if needed,
+ // the ScanKey method below wants a real column as input
+ if (col.getItemExpr()->getOperatorType() == ITM_VEG_REFERENCE)
+ {
+ const ValueIdSet &vegMembers =
+ static_cast<VEGReference *>(col.getItemExpr())->
+ getVEG()->getAllValues();
+ for (ValueId b=vegMembers.init();
+ vegMembers.next(b);
+ vegMembers.advance(b))
+ if (b.getItemExpr()->getOperatorType() == ITM_BASECOLUMN)
+ col = b;
--- End diff --
The ScanKey::isAKeyPredicateForColumn method below relies on
ScanKey::expressionContainsColumn() as a test. That method should be ok with
any VEG member, index or base column, just not with the VEGReference itself.
This brings up some interesting questions, whether this code is necessary and
also whether there is a potential issue with equating rows of another table
with a constant that is not in a VEG (at this time I think we are ok on that
one). I'm investigating this a bit further and will add a fix and/or another
comment here.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---