GroupJunction extends AbstractGroupOrRangeJunction { @Override OrganizedOperands organizeOperands(ExecutionContext context) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException { List<Object> evalOperands = new ArrayList<>(_operands.length); int indexCount = 0; boolean foundPreferredCondition = false; if (this.getOperator() == LITERAL_and) { if (context instanceof QueryExecutionContext && ((QueryExecutionContext) context).hasHints() && ((QueryExecutionContext) context).hasMultiHints()) { for (CompiledValue operand : _operands) { if (operand.getPlanInfo(context).evalAsFilter) { indexCount++; evalOperands.add(0, operand); } else { evalOperands.add(operand); } } } else { Filter currentBestFilter = null; int currentBestFilterSize = -1; indexCount = 1; for (CompiledValue operand : _operands) { PlanInfo pi = operand.getPlanInfo(context); if (pi.evalAsFilter && pi.indexes.size() == 1) { if (pi.isPreferred) { if (currentBestFilter != null) { evalOperands.add(currentBestFilter); } currentBestFilter = (Filter) operand; currentBestFilterSize = ((Filter) operand).getSizeEstimate(context); foundPreferredCondition = true; continue; } if (currentBestFilter == null) { currentBestFilter = (Filter) operand; currentBestFilterSize = ((Filter) operand).getSizeEstimate(context); } else if (foundPreferredCondition || currentBestFilter.isBetterFilter((Filter) operand, context, currentBestFilterSize)) { evalOperands.add(operand); } else { evalOperands.add(currentBestFilter); currentBestFilter = (Filter) operand; currentBestFilterSize = ((Filter) operand).getSizeEstimate(context); } } else if (!operand.isDependentOnCurrentScope(context)) { Support.assertionFailed( "An independentoperand should not ever be present as operand inside a GroupJunction as it should always be present only in CompiledJunction"); } else { if (pi.indexes.size() > 1) { evalOperands.add(0, operand); } else { evalOperands.add(operand); } } } if (currentBestFilter != null) { evalOperands.add(0, currentBestFilter); } } } else { indexCount = _operands.length; evalOperands.addAll(Arrays.asList(_operands).subList(0, indexCount)); } if (getIterOperands() != null) { evalOperands.add(getIterOperands()); } return createOrganizedOperandsObject(indexCount, evalOperands); } GroupJunction(int operator, RuntimeIterator[] indpndntItr, boolean isCompleteExpansion,
      CompiledValue[] operands); private  GroupJunction(AbstractGroupOrRangeJunction oldGJ, boolean completeExpansion,
      RuntimeIterator[] indpnds, CompiledValue iterOp); @Override int getSizeEstimate(ExecutionContext context);  }
@Test public void organizeOperandsForOROperationShouldUseAllOperands() throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException, FunctionDomainException { groupJunction = spy(new GroupJunction(OQLLexerTokenTypes.LITERAL_or, new RuntimeIterator[] {}, true, new CompiledValue[] {nameIsClark, aliasNotBatman})); OrganizedOperands organizedOperands = groupJunction.organizeOperands(queryExecutionContext); assertThat(organizedOperands).isNotNull(); verify(groupJunction, times(1)).createOrganizedOperandsObject(indexCaptor.capture(), evalOperandsCaptor.capture()); assertThat(indexCaptor.getValue()).isEqualTo(2); assertThat(evalOperandsCaptor.getValue()).isEqualTo(Arrays.asList(nameIsClark, aliasNotBatman)); }
@Test public void organizeOperandsForANDOperationShouldUseAllOperandsAndFiltersWhenHintsHaveBeenProvided() throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException, FunctionDomainException { groupJunction = spy(new GroupJunction(OQLLexerTokenTypes.LITERAL_and, new RuntimeIterator[] {}, true, new CompiledValue[] {nameIsClark, aliasNotBatman, aliasNotEqualsNameFilter})); when(queryExecutionContext.hasHints()).thenReturn(true); when(queryExecutionContext.hasMultiHints()).thenReturn(true); OrganizedOperands organizedOperands = groupJunction.organizeOperands(queryExecutionContext); assertThat(organizedOperands).isNotNull(); verify(groupJunction, times(1)).createOrganizedOperandsObject(indexCaptor.capture(), evalOperandsCaptor.capture()); assertThat(indexCaptor.getValue()).isEqualTo(1); assertThat(evalOperandsCaptor.getValue()) .isEqualTo(Arrays.asList(aliasNotEqualsNameFilter, nameIsClark, aliasNotBatman)); }
@Test public void organizeOperandsForANDOperationShouldUseSingleIndexOptimization() throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException, FunctionDomainException { groupJunction = spy(new GroupJunction(OQLLexerTokenTypes.LITERAL_and, new RuntimeIterator[] {}, true, new CompiledValue[] {aliasNotBatman, aliasNotEqualsNameFilter})); OrganizedOperands organizedOperands = groupJunction.organizeOperands(queryExecutionContext); assertThat(organizedOperands).isNotNull(); verify(groupJunction, times(1)).createOrganizedOperandsObject(indexCaptor.capture(), evalOperandsCaptor.capture()); assertThat(indexCaptor.getValue()).isEqualTo(1); assertThat(evalOperandsCaptor.getValue()) .isEqualTo(Arrays.asList(aliasNotEqualsNameFilter, aliasNotBatman)); }
@Test public void organizeOperandsForANDOperationShouldUseSingleIndexOptimizationAndOverrideBestFilterWithPreferredOne() throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException, FunctionDomainException { groupJunction = spy(new GroupJunction(OQLLexerTokenTypes.LITERAL_and, new RuntimeIterator[] {}, true, new CompiledValue[] {aliasNotBatman, aliasNotEqualsNameFilter, aliasNotEqualsNameFilterWithPreferredFlag})); OrganizedOperands organizedOperands = groupJunction.organizeOperands(queryExecutionContext); assertThat(organizedOperands).isNotNull(); verify(groupJunction, times(1)).createOrganizedOperandsObject(indexCaptor.capture(), evalOperandsCaptor.capture()); assertThat(indexCaptor.getValue()).isEqualTo(1); assertThat(evalOperandsCaptor.getValue()).isEqualTo(Arrays.asList( aliasNotEqualsNameFilterWithPreferredFlag, aliasNotBatman, aliasNotEqualsNameFilter)); }
@Test public void organizeOperandsForANDOperationShouldUseAllOperandsAndFiltersWhenHintsHaveNotBeenProvidedAndSingleIndexOptimizationCanNotBeApplied() throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException, FunctionDomainException { groupJunction = spy(new GroupJunction(OQLLexerTokenTypes.LITERAL_and, new RuntimeIterator[] {}, true, new CompiledValue[] {nameIsClark, aliasNotEqualsNameFilterWithMultipleIndexes})); OrganizedOperands organizedOperands = groupJunction.organizeOperands(queryExecutionContext); assertThat(organizedOperands).isNotNull(); verify(groupJunction, times(1)).createOrganizedOperandsObject(indexCaptor.capture(), evalOperandsCaptor.capture()); assertThat(indexCaptor.getValue()).isEqualTo(1); assertThat(evalOperandsCaptor.getValue()) .isEqualTo(Arrays.asList(aliasNotEqualsNameFilterWithMultipleIndexes, nameIsClark)); }