@Override
    public QueryResults execute( final QueryContext queryContext,
                                 final QueryCommand query ) throws QueryCancelledException, RepositoryException {
        CheckArg.isNotNull(queryContext, "queryContext");
        CheckArg.isNotNull(query, "query");
        final ScanQueryContext context = (ScanQueryContext)queryContext;

        checkCancelled(context);

        // Validate that all of the referenced variables have been provided ...
        Visitors.visitAll(query, new Visitors.AbstractVisitor() {
            @Override
            public void visit( BindVariableName obj ) {
                if (!context.getVariables().keySet().contains(obj.getBindVariableName())) {
                    context.getProblems().addError(GraphI18n.missingVariableValue, obj.getBindVariableName());
                }
            }
        });

        boolean trace = LOGGER.isTraceEnabled();
        if (trace) {
            LOGGER.trace("Beginning to process query {3} against workspace(s) {0} in '{1}' repository: {2}",
                         context.getWorkspaceNames(), repositoryName, query, context.id());
        }

        // Create the canonical plan ...
        long start = System.nanoTime();
        PlanNode plan = planner.createPlan(context, query);
        long duration = Math.abs(System.nanoTime() - start);
        Statistics stats = new Statistics(duration);
        final String workspaceName = context.getWorkspaceNames().iterator().next();

        if (trace) {
            LOGGER.trace("Computed canonical query plan for query {0}: {1}", context.id(), plan);
        }

        checkCancelled(context);
        Columns resultColumns = null;
        if (!context.getProblems().hasErrors()) {
            // Optimize the plan ...
            start = System.nanoTime();
            PlanNode optimizedPlan = optimizer.optimize(context, plan);
            duration = Math.abs(System.nanoTime() - start);
            stats = stats.withOptimizationTime(duration);

            if (trace) {
                LOGGER.trace("Computed optimized query plan for query {0}:\n{1}", context.id(), optimizedPlan);
            }

            // Find the query result columns ...
            start = System.nanoTime();

            // Determine the Columns object for specific nodes in the plan, and store them in the context ...
            optimizedPlan.apply(Traversal.POST_ORDER, new PlanNode.Operation() {

                @Override
                public void apply( PlanNode node ) {
                    Columns columns = null;
                    switch (node.getType()) {
                        case PROJECT:
                        case SOURCE:
                            columns = determineProjectedColumns(node, context);
                            assert columns != null;
                            break;
                        case JOIN:
                            Columns leftColumns = context.columnsFor(node.getFirstChild());
                            Columns rightColumns = context.columnsFor(node.getLastChild());
                            columns = leftColumns.with(rightColumns);
                            assert columns != null;
                            break;
                        case DEPENDENT_QUERY:
                            columns = context.columnsFor(node.getLastChild());
                            assert columns != null;
                            break;
                        case SET_OPERATION:
                            leftColumns = context.columnsFor(node.getFirstChild());
                            rightColumns = context.columnsFor(node.getLastChild());
                            if (checkUnionCompatible(leftColumns, rightColumns, context, query)) {
                                columns = leftColumns;
                                assert columns != null;
                            }
                            break;
                        case INDEX:
                            // do nothing with indexes ...
                            break;
                        default:
                            assert node.getChildCount() == 1;
                            columns = context.columnsFor(node.getFirstChild());
                            assert columns != null;
                            break;
                    }
                    if (columns != null) {
                        context.addColumnsFor(node, columns);
                    }
                }
            });
            Problems problems = context.getProblems();
            if (problems.hasErrors()) {
                throw new RepositoryException(JcrI18n.problemsWithQuery.text(query, problems.toString()));
            } else if (LOGGER.isDebugEnabled() && problems.hasWarnings()) {
                LOGGER.debug("There are several warnings with this query: {0}\n{1}", query, problems.toString());
            }

            resultColumns = context.columnsFor(optimizedPlan);
            assert resultColumns != null;
            duration = Math.abs(System.nanoTime() - start);
            stats = stats.withResultsFormulationTime(duration);

            if (trace) {
                LOGGER.trace("Computed output columns for query {0}: {1}", context.id(), resultColumns);
            }

            if (!context.getProblems().hasErrors()) {
                checkCancelled(context);
                // Execute the plan ...
                try {
                    start = System.nanoTime();
                    if (trace) {
                        LOGGER.trace("Start executing query {0}", context.id());
                    }
                    QueryResults results = executeOptimizedQuery(context, query, stats, optimizedPlan);
                    if (trace) {
                        LOGGER.trace("Stopped executing query {0}: {1}", context.id(), stats);
                    }
                    return results;
                } finally {
                    duration = Math.abs(System.nanoTime() - start);
                    stats = stats.withExecutionTime(duration);
                }
            }
        }
        // Check whether the query was cancelled during execution ...
        checkCancelled(context);

        if (resultColumns == null) resultColumns = ResultColumns.EMPTY;

        // There were problems somewhere ...
        int width = resultColumns.getColumns().size();
        CachedNodeSupplier cachedNodes = context.getNodeCache(workspaceName);
        return new Results(resultColumns, stats, NodeSequence.emptySequence(width), cachedNodes, context.getProblems(), null);
    }
@ Override public QueryResults execute ( final QueryContext queryContext , final QueryCommand query ) throws QueryCancelledException , RepositoryException { CheckArg . isNotNull ( queryContext , "queryContext" ) ; CheckArg . isNotNull ( query , "query" ) ; final ScanQueryContext context = ( ScanQueryContext ) queryContext ; checkCancelled ( context ) ; Visitors . visitAll ( query , new Visitors . AbstractVisitor ( ) { @ Override public void visit ( BindVariableName obj ) { if ( ! context . getVariables ( ) . keySet ( ) . contains ( obj . getBindVariableName ( ) ) ) { context . getProblems ( ) . addError ( GraphI18n . missingVariableValue , obj . getBindVariableName ( ) ) ; } } } ) ; boolean trace = LOGGER . isTraceEnabled ( ) ; if ( trace ) { LOGGER . trace ( "Beginning to process query {3} against workspace(s) {0} in '{1}' repository: {2}" , context . getWorkspaceNames ( ) , repositoryName , query , context . id ( ) ) ; } long start = System . nanoTime ( ) ; PlanNode plan = planner . createPlan ( context , query ) ; long duration = Math . abs ( System . nanoTime ( ) - start ) ; Statistics stats = new Statistics ( duration ) ; final String workspaceName = context . getWorkspaceNames ( ) . iterator ( ) . next ( ) ; if ( trace ) { LOGGER . trace ( "Computed canonical query plan for query {0}: {1}" , context . id ( ) , plan ) ; } checkCancelled ( context ) ; Columns resultColumns = null ; if ( ! context . getProblems ( ) . hasErrors ( ) ) { start = System . nanoTime ( ) ; PlanNode optimizedPlan = optimizer . optimize ( context , plan ) ; duration = Math . abs ( System . nanoTime ( ) - start ) ; stats = stats . withOptimizationTime ( duration ) ; if ( trace ) { LOGGER . trace ( "Computed optimized query plan for query {0}:\n{1}" , context . id ( ) , optimizedPlan ) ; } start = System . nanoTime ( ) ; optimizedPlan . apply ( Traversal . POST_ORDER , new PlanNode . Operation ( ) { @ Override public void apply ( PlanNode node ) { Columns columns = null ; switch ( node . getType ( ) ) { case PROJECT : case SOURCE : columns = determineProjectedColumns ( node , context ) ; assert columns != null ; break ; case JOIN : Columns leftColumns = context . columnsFor ( node . getFirstChild ( ) ) ; Columns rightColumns = context . columnsFor ( node . getLastChild ( ) ) ; columns = leftColumns . with ( rightColumns ) ; assert columns != null ; break ; case DEPENDENT_QUERY : columns = context . columnsFor ( node . getLastChild ( ) ) ; assert columns != null ; break ; case SET_OPERATION : leftColumns = context . columnsFor ( node . getFirstChild ( ) ) ; rightColumns = context . columnsFor ( node . getLastChild ( ) ) ; if ( checkUnionCompatible ( leftColumns , rightColumns , context , query ) ) { columns = leftColumns ; assert columns != null ; } break ; case INDEX : break ; default : assert node . getChildCount ( ) == 1 ; columns = context . columnsFor ( node . getFirstChild ( ) ) ; assert columns != null ; break ; } if ( columns != null ) { context . addColumnsFor ( node , columns ) ; } } } ) ; Problems problems = context . getProblems ( ) ; if ( problems . hasErrors ( ) ) { throw new RepositoryException ( JcrI18n . problemsWithQuery . text ( query , problems . toString ( ) ) ) ; } else if ( LOGGER . isDebugEnabled ( ) && problems . hasWarnings ( ) ) { LOGGER . debug ( "There are several warnings with this query: {0}\n{1}" , query , problems . toString ( ) ) ; } resultColumns = context . columnsFor ( optimizedPlan ) ; assert resultColumns != null ; duration = Math . abs ( System . nanoTime ( ) - start ) ; stats = stats . withResultsFormulationTime ( duration ) ; if ( trace ) { LOGGER . trace ( "Computed output columns for query {0}: {1}" , context . id ( ) , resultColumns ) ; } if ( ! context . getProblems ( ) . hasErrors ( ) ) { checkCancelled ( context ) ; try { start = System . nanoTime ( ) ; if ( trace ) { LOGGER . trace ( "Start executing query {0}" , context . id ( ) ) ; } QueryResults results = executeOptimizedQuery ( context , query , stats , optimizedPlan ) ; if ( trace ) { LOGGER . trace ( "Stopped executing query {0}: {1}" , context . id ( ) , stats ) ; } return results ; } finally { duration = Math . abs ( System . nanoTime ( ) - start ) ; stats = stats . withExecutionTime ( duration ) ; } } } checkCancelled ( context ) ; if ( resultColumns == null ) resultColumns = ResultColumns . EMPTY ; int width = resultColumns . getColumns ( ) . size ( ) ; CachedNodeSupplier cachedNodes = context . getNodeCache ( workspaceName ) ; return new Results ( resultColumns , stats , NodeSequence . emptySequence ( width ) , cachedNodes , context . getProblems ( ) , null ) ; }
Execute the supplied query by planning, optimizing, and then processing it.

@param queryContext the context in which the query should be executed; same instance as returned by
{@link #createQueryContext}
@param query the query that is to be executed
@return the query results; never null
@throws IllegalArgumentException if the context or query references are null
@throws QueryCancelledException if the query was cancelled
@throws RepositoryException if there was a problem executing the query