Package com.foundationdb.qp.operator

Source Code of com.foundationdb.qp.operator.EmitBoundRow_Nested$Execution

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.qp.operator;

import com.foundationdb.qp.row.Row;
import com.foundationdb.qp.rowtype.RowType;
import com.foundationdb.server.explain.*;
import com.foundationdb.server.explain.std.LookUpOperatorExplainer;
import com.foundationdb.util.ArgumentValidation;
import com.foundationdb.util.tap.InOutTap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**

<h1>Overview</h1>

EmitBoundRow_Nested recovers a row (or subrow) from a nested loop.

When an <code>UPDATE</code> statement involves complex joins, the row
to be updated is no longer an immediate input.

<h1>Arguments</h1>

<ul>

<li><b>RowType inputRowType:</b> The input row that triggers the lookup.

<li><b>RowType outputRowType:</b> The desired row type.

<li><b>RowType boundRowType:</b> The type in the bindings.

<li><b>int bindingPosition:</b> Indicates target row's position in the query context.

</ul>

<h1>Behavior</h1>
The outer row is fetched from the query context for every inner row. No database access is required.

<h1>Output</h1>

The bound row (or a subrow).

<h1>Assumptions</h1>

None.

<h1>Performance</h1>

  No datbase access.

<h1>Memory Requirements</h1>

  No storage of its own.

*/

class EmitBoundRow_Nested extends Operator
{
    // Object interface

    @Override
    public String toString()
    {
        return String.format("%s(%s -> %s)", getClass().getSimpleName(), inputRowType, outputRowType);
    }

    // Operator interface

    @Override
    public void findDerivedTypes(Set<RowType> derivedTypes)
    {
        inputOperator.findDerivedTypes(derivedTypes);
    }

    @Override
    protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor)
    {
        return new Execution(context, inputOperator.cursor(context, bindingsCursor));
    }

    @Override
    public List<Operator> getInputOperators()
    {
        List<Operator> result = new ArrayList<>(1);
        result.add(inputOperator);
        return result;
    }

    @Override
    public String describePlan()
    {
        return describePlan(inputOperator);
    }

    // EmitBoundRow_Nested interface

    public EmitBoundRow_Nested(Operator inputOperator,
                            RowType inputRowType,
                            RowType outputRowType,
                            RowType boundRowType,
                            int bindingPosition)
    {
        validateArguments(inputRowType, outputRowType, boundRowType, bindingPosition);
        this.inputOperator = inputOperator;
        this.inputRowType = inputRowType;
        this.outputRowType = outputRowType;
        this.boundRowType = boundRowType;
        this.bindingPosition = bindingPosition;
    }

    // For use by this class

    private void validateArguments(RowType inputRowType,
                                   RowType outputRowType,
                                   RowType boundRowType,
                                   int bindingPosition)
    {
        ArgumentValidation.notNull("inputRowType", inputRowType);
        ArgumentValidation.notNull("outputRowType", outputRowType);
        ArgumentValidation.notNull("boundRowType", boundRowType);
        ArgumentValidation.isTrue("bindingPosition >= 0", bindingPosition >= 0);
    }

    // Class state

    private static final Logger LOG = LoggerFactory.getLogger(EmitBoundRow_Nested.class);
    private static final InOutTap TAP_OPEN = OPERATOR_TAP.createSubsidiaryTap("operator: EmitBoundRow_Nested open");
    private static final InOutTap TAP_NEXT = OPERATOR_TAP.createSubsidiaryTap("operator: EmitBoundRow_Nested next");

    // Object state

    private final Operator inputOperator;
    private final RowType inputRowType, outputRowType, boundRowType;
    private final int bindingPosition;

    @Override
    public CompoundExplainer getExplainer(ExplainContext context)
    {
        Attributes atts = new Attributes();
        atts.put(Label.BINDING_POSITION, PrimitiveExplainer.getInstance(bindingPosition));
        atts.put(Label.OUTPUT_TYPE, outputRowType.getExplainer(context));
        return new LookUpOperatorExplainer(getName(), atts, inputRowType, false, inputOperator, context);
    }

    // Inner classes

    private class Execution extends ChainedCursor
    {
        // Cursor interface

        @Override
        public void open()
        {
            TAP_OPEN.in();
            try {
                super.open();
            } finally {
                TAP_OPEN.out();
            }
        }

        @Override
        public Row next()
        {
            if (TAP_NEXT_ENABLED) {
                TAP_NEXT.in();
            }
            try {
                if (CURSOR_LIFECYCLE_ENABLED) {
                    CursorLifecycle.checkIdleOrActive(this);
                }
                checkQueryCancelation();
                Row row = input.next();
                if (LOG_EXECUTION) {
                    LOG.debug("EmitBoundRow: {}", row == null ? null : row);
                }
                if (row == null) {
                    setIdle();
                }
                else  {
                    assert (row.rowType() == inputRowType);
                    Row rowFromBindings = bindings.getRow(bindingPosition);
                    assert (rowFromBindings.rowType() == boundRowType);
                    if (boundRowType == outputRowType) {
                        row = rowFromBindings;
                    }
                    else {
                        row = rowFromBindings.subRow(outputRowType);
                        assert (row != null) : rowFromBindings;
                    }
                }
                if (LOG_EXECUTION) {
                    LOG.debug("EmitBoundRow_Nested: yield {}", row);
                }
                return row;
            } finally {
                if (TAP_NEXT_ENABLED) {
                    TAP_NEXT.out();
                }
            }
        }

        // Execution interface

        Execution(QueryContext context, Cursor input)
        {
            super(context, input);
        }
    }
}
TOP

Related Classes of com.foundationdb.qp.operator.EmitBoundRow_Nested$Execution

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.