use of org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalStep in project sqlg by pietermartin.
the class BaseStrategy method handleOptionalStep.
private void handleOptionalStep(int optionalStepNestedCount, OptionalStep<?> optionalStep, Traversal.Admin<?, ?> traversal, MutableInt pathCount) {
// The currentTreeNode here is the node that will need the left join in the sql generation
this.optionalStepStack.add(this.currentTreeNodeNode);
Preconditions.checkState(this.optionalStepStack.size() == optionalStepNestedCount);
Traversal.Admin<?, ?> optionalTraversal = optionalStep.getLocalChildren().get(0);
ReplacedStep<?, ?> previousReplacedStep = this.sqlgStep.getReplacedSteps().get(this.sqlgStep.getReplacedSteps().size() - 1);
previousReplacedStep.setLeftJoin(true);
List<Step<?, ?>> optionalTraversalSteps = new ArrayList(optionalTraversal.getSteps());
ListIterator<Step<?, ?>> optionalStepsIterator = optionalTraversalSteps.listIterator();
while (optionalStepsIterator.hasNext()) {
Step internalOptionalStep = optionalStepsIterator.next();
if (internalOptionalStep instanceof VertexStep || internalOptionalStep instanceof EdgeVertexStep || internalOptionalStep instanceof EdgeOtherVertexStep) {
handleVertexStep(optionalStepsIterator, (AbstractStep<?, ?>) internalOptionalStep, pathCount);
// I.e. there was no results for the chooseSteps traversal.
for (int i = optionalStepNestedCount; i < this.chooseStepStack.size(); i++) {
ReplacedStepTree.TreeNode treeNode = this.chooseStepStack.get(i);
this.currentReplacedStep.markAsJoinToLeftJoin();
treeNode.addReplacedStep(this.currentReplacedStep);
}
} else if (internalOptionalStep instanceof OptionalStep) {
handleOptionalStep(optionalStepNestedCount + 1, (OptionalStep) internalOptionalStep, traversal, pathCount);
} else if (internalOptionalStep instanceof ComputerAwareStep.EndStep) {
break;
} else if (internalOptionalStep instanceof HasStep) {
handleHasSteps(optionalStepsIterator, pathCount.getValue());
} else {
throw new IllegalStateException("Unhandled step nested in OptionalStep " + internalOptionalStep.getClass().getName());
}
}
// In that case it will not be a direct step of the traversal.
if (traversal.getSteps().contains(optionalStep)) {
traversal.removeStep(optionalStep);
}
}
use of org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalStep in project sqlg by pietermartin.
the class SqlgOptionalStepStrategy method apply.
@Override
public void apply(final Traversal.Admin<?, ?> traversal) {
// noinspection OptionalGetWithoutIsPresent
if (!(traversal.getGraph().get() instanceof SqlgGraph)) {
return;
}
List<OptionalStep> optionalSteps = TraversalHelper.getStepsOfAssignableClass(OptionalStep.class, traversal);
for (OptionalStep<S> optionalStep : optionalSteps) {
// The predicate branch step is a local traversal.
// As such if it contains a ReducingBarrierStep the SqlgBranchStepBarrier will not work.
Traversal.Admin<S, S> optionalTraversal = optionalStep.getLocalChildren().get(0);
List<ReducingBarrierStep> reducingBarrierSteps = TraversalHelper.getStepsOfAssignableClass(ReducingBarrierStep.class, optionalTraversal);
if (!reducingBarrierSteps.isEmpty()) {
continue;
}
SqlgOptionalStepBarrier sqlgOptionalStepBarrier = new SqlgOptionalStepBarrier<>(traversal, optionalTraversal);
for (String label : optionalStep.getLabels()) {
sqlgOptionalStepBarrier.addLabel(label);
}
TraversalHelper.replaceStep(optionalStep, sqlgOptionalStepBarrier, optionalStep.getTraversal());
}
}
use of org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalStep in project sqlg by pietermartin.
the class BaseStrategy method handleOrderGlobalSteps.
protected void handleOrderGlobalSteps(ListIterator<Step<?, ?>> iterator, MutableInt pathCount) {
// Collect the OrderGlobalSteps
while (iterator.hasNext()) {
Step<?, ?> step = iterator.next();
if (step instanceof OrderGlobalStep) {
if (optimizable((OrderGlobalStep) step)) {
// add the label if any
for (String label : step.getLabels()) {
this.currentReplacedStep.addLabel(pathCount.getValue() + BaseStrategy.PATH_LABEL_SUFFIX + label);
}
// The step might not be here. For instance if it was nested in a chooseStep where the chooseStep logic already removed the step.
if (this.traversal.getSteps().contains(step)) {
this.traversal.removeStep(step);
}
iterator.previous();
Step previousStep = iterator.previous();
if (previousStep instanceof SelectOneStep) {
SelectOneStep selectOneStep = (SelectOneStep) previousStep;
String key = (String) selectOneStep.getScopeKeys().iterator().next();
this.currentReplacedStep.getSqlgComparatorHolder().setPrecedingSelectOneLabel(key);
List<Pair<Traversal.Admin<?, ?>, Comparator<?>>> comparators = ((OrderGlobalStep) step).getComparators();
// get the step for the label
Optional<ReplacedStep<?, ?>> labeledReplacedStep = this.sqlgStep.getReplacedSteps().stream().filter(r -> {
Set<String> labels = r.getLabels();
for (String label : labels) {
String stepLabel = SqlgUtil.originalLabel(label);
if (stepLabel.equals(key)) {
return true;
} else {
return false;
}
}
return false;
}).findAny();
Preconditions.checkState(labeledReplacedStep.isPresent());
ReplacedStep<?, ?> replacedStep = labeledReplacedStep.get();
replacedStep.getSqlgComparatorHolder().setComparators(comparators);
// add a label if the step does not yet have one and is not a leaf node
if (replacedStep.getLabels().isEmpty()) {
replacedStep.addLabel(pathCount.getValue() + BaseStrategy.PATH_LABEL_SUFFIX + BaseStrategy.SQLG_PATH_ORDER_RANGE_LABEL);
}
} else if (previousStep instanceof OptionalStep) {
throw new RuntimeException("not yet implemented");
} else if (previousStep instanceof ChooseStep) {
// The order applies to the current replaced step and the previous ChooseStep
List<Pair<Traversal.Admin<?, ?>, Comparator<?>>> comparators = ((OrderGlobalStep) step).getComparators();
this.currentReplacedStep.getSqlgComparatorHolder().setComparators(comparators);
// add a label if the step does not yet have one and is not a leaf node
if (this.currentReplacedStep.getLabels().isEmpty()) {
this.currentReplacedStep.addLabel(pathCount.getValue() + BaseStrategy.PATH_LABEL_SUFFIX + BaseStrategy.SQLG_PATH_ORDER_RANGE_LABEL);
}
} else {
List<Pair<Traversal.Admin<?, ?>, Comparator<?>>> comparators = ((OrderGlobalStep) step).getComparators();
this.currentReplacedStep.getSqlgComparatorHolder().setComparators(comparators);
// add a label if the step does not yet have one and is not a leaf node
if (this.currentReplacedStep.getLabels().isEmpty()) {
this.currentReplacedStep.addLabel(pathCount.getValue() + BaseStrategy.PATH_LABEL_SUFFIX + BaseStrategy.SQLG_PATH_ORDER_RANGE_LABEL);
}
}
iterator.next();
iterator.next();
} else {
return;
}
} else {
// break on the first step that is not a OrderGlobalStep
iterator.previous();
break;
}
}
}
use of org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalStep in project sqlg by pietermartin.
the class BaseStrategy method unoptimizableOptionalStep.
boolean unoptimizableOptionalStep(OptionalStep<?> optionalStep) {
if (!this.optionalStepStack.isEmpty()) {
return true;
}
Traversal.Admin<?, ?> optionalTraversal = optionalStep.getLocalChildren().get(0);
List<Step> optionalTraversalSteps = new ArrayList<>(optionalTraversal.getSteps());
// Can not optimize if the traversal contains a RangeGlobalStep
List<Step> rangeGlobalSteps = optionalTraversalSteps.stream().filter(p -> p.getClass().equals(RangeGlobalStep.class)).collect(Collectors.toList());
if (rangeGlobalSteps.size() > 1) {
return true;
}
if (rangeGlobalSteps.size() > 0) {
Step rangeGlobalStep = rangeGlobalSteps.get(0);
// Only if the rangeGlobalStep is the last step can it be optimized
if (optionalTraversalSteps.get(optionalTraversalSteps.size() - 1) != rangeGlobalStep) {
return true;
}
}
ListIterator<Step> stepListIterator = optionalTraversalSteps.listIterator();
while (stepListIterator.hasNext()) {
Step internalOptionalStep = stepListIterator.next();
if (!(internalOptionalStep instanceof VertexStep || internalOptionalStep instanceof EdgeVertexStep || internalOptionalStep instanceof EdgeOtherVertexStep || internalOptionalStep instanceof ComputerAwareStep.EndStep || internalOptionalStep instanceof OptionalStep || internalOptionalStep instanceof HasStep || internalOptionalStep instanceof OrderGlobalStep || internalOptionalStep instanceof RangeGlobalStep)) {
return true;
}
}
List<Step> optionalSteps = optionalTraversalSteps.stream().filter(p -> p.getClass().equals(OptionalStep.class)).collect(Collectors.toList());
for (Step step : optionalSteps) {
if (unoptimizableOptionalStep((OptionalStep<?>) step)) {
return true;
}
}
return false;
}
Aggregations