31 #include <unordered_set>
42 if (condition ==
nullptr) {
45 return mk<Conjunction>(std::move(condition), std::move(c));
57 auto pattern = indexOperation->getRangePattern();
61 for (
Expression*
p : indexOperation->getRangePattern().first) {
62 updatedPattern.first.emplace_back(
p->clone());
64 for (
Expression*
p : indexOperation->getRangePattern().second) {
65 updatedPattern.second.emplace_back(
p->clone());
67 for (
auto i : attributesToDischarge) {
76 mk<TupleElement>(indexOperation->getTupleId(),
i),
78 condition = addCondition(std::move(condition),
souffle::clone(lowerBound));
84 mk<TupleElement>(indexOperation->getTupleId(),
i),
86 condition = addCondition(std::move(condition),
souffle::clone(upperBound));
90 updatedPattern.first[
i] = mk<UndefValue>();
91 updatedPattern.second[
i] = mk<UndefValue>();
99 if (
const IndexScan* iscan =
dynamic_cast<IndexScan*
>(node.get())) {
100 node = mk<IndexScan>(iscan->getRelation(), iscan->getTupleId(),
101 std::move(updatedPattern), std::move(
filter), iscan->getProfileText());
102 }
else if (
const ParallelIndexScan* pscan =
103 dynamic_cast<ParallelIndexScan*
>(node.get())) {
104 node = mk<ParallelIndexScan>(pscan->getRelation(), pscan->getTupleId(),
105 std::move(updatedPattern), std::move(
filter), pscan->getProfileText());
106 }
else if (
const IndexChoice* ichoice =
dynamic_cast<IndexChoice*
>(node.get())) {
107 node = mk<IndexChoice>(ichoice->getRelation(), ichoice->getTupleId(),
108 souffle::clone(&ichoice->getCondition()), std::move(updatedPattern),
109 std::move(
filter), ichoice->getProfileText());
110 }
else if (
const IndexAggregate* iagg =
dynamic_cast<IndexAggregate*
>(node.get())) {
114 auto strengthenedCondition = addCondition(
115 Own<Condition>(
souffle::clone(&iagg->getCondition())), std::move(condition));
117 node = mk<IndexAggregate>(std::move(nestedOp), iagg->getFunction(),
119 std::move(strengthenedCondition), std::move(updatedPattern),
122 fatal(
"New IndexOperation subclass found but not supported while making index.");
133 std::function<Own<Node>(Own<Node>)> removeEmptyIndexRewriter = [&](Own<Node> node) -> Own<Node> {
135 if (
const IndexOperation* indexOperation =
dynamic_cast<IndexOperation*
>(node.get())) {
136 auto pattern = indexOperation->getRangePattern();
137 size_t length = pattern.first.size();
138 bool foundRealIndexableOperation =
false;
140 for (
size_t i = 0;
i < length; ++
i) {
146 foundRealIndexableOperation =
true;
149 if (!foundRealIndexableOperation) {
152 if (
const IndexScan* iscan =
dynamic_cast<IndexScan*
>(node.get())) {
153 node = mk<Scan>(iscan->getRelation(), iscan->getTupleId(),
155 }
else if (
const ParallelIndexScan* pscan =
156 dynamic_cast<ParallelIndexScan*
>(node.get())) {
157 node = mk<ParallelScan>(pscan->getRelation(), pscan->getTupleId(),
159 }
else if (
const IndexChoice* ichoice =
dynamic_cast<IndexChoice*
>(node.get())) {
160 node = mk<Choice>(ichoice->getRelation(), ichoice->getTupleId(),
162 souffle::clone(&ichoice->getOperation()), ichoice->getProfileText());
163 }
else if (
const IndexAggregate* iagg =
dynamic_cast<IndexAggregate*
>(node.get())) {
164 node = mk<Aggregate>(
souffle::clone(&iagg->getOperation()), iagg->getFunction(),
168 fatal(
"New IndexOperation subclass found but not supported while transforming "