All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.kv.impl.query.compiler.StaticContext Maven / Gradle / Ivy

/*-
 * Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle NoSQL
 * Database made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle NoSQL Database for a copy of the license and
 * additional information.
 */

package oracle.kv.impl.query.compiler;


import java.util.HashMap;
import java.util.Map;

import oracle.kv.impl.query.QueryException;
import oracle.kv.impl.query.types.ExprType;

/**
 * StaticContext stores various pieces of info needed during compilation.
 * The reason why we use StaticContext, rather than the QueryControlBlock,
 * is that the relevan info may be scoped. So, multiple StaticContext
 * instances may be created during compilation, each defining a nested
 * scope.
 */
public class StaticContext {

    private final StaticContext theParent;

    private HashMap theFunctions;

    private HashMap theVariables;


    StaticContext(StaticContext parent) {
        theParent = parent;
    }

    boolean isRoot() {
        return theParent == null;
    }

    /*
     * VarInfo is used to store info about an external var. This info is
     * collected, for all external vars, after compilation is done and is
     * then stored in the PreparedStatement. The collected info is needed
     * during query execution, and by extracting it from the ExprVars that
     * represent the external vars during compilation and storing it into
     * the PreparedStatement we can throw away the expressions graph and
     * the static context after query compilation is done.
     */
    public static class VarInfo {

        private final int theId;

        private final ExprType theType;

        VarInfo(ExprVar var) {
            theId = var.getId();
            theType = var.getType();
        }

        private VarInfo(int id,
                        ExprType type) {
            theId = id;
            theType = type;
        }

        /* for use by deserialization -- see PreparedStatementImpl */
        public static VarInfo createVarInfo(int id, ExprType type) {
            return new VarInfo(id, type);
        }

        public int getId() {
            return theId;
        }

        public ExprType getType() {
            return theType;
        }
    }

    void addVariable(ExprVar var) {

        if (theVariables == null) {
            theVariables = new HashMap();
        }

        if (theVariables.put(var.getName(), var) != null) {
            throw new QueryException(
                "Duplicate declaration for variable " + var.getName(),
                var.getLocation());
        }
    }

    ExprVar findVariable(String name) {
        return findVariable(name, false);
    }

    ExprVar findVariable(String name, boolean local) {

        if (local) {
            if (theVariables == null) {
                return null;
            }
            ExprVar var = theVariables.get(name);
            return var;
        }

        ExprVar var = null;
        StaticContext sctx = this;

        while (var == null && sctx != null) {
           if (sctx.theVariables != null) {
               var = sctx.theVariables.get(name);
           }
            sctx = sctx.theParent;
        }

        return var;
    }

    public Map getExternalVars() {

        Map varsMap = new HashMap();

        if (theVariables == null) {
            return varsMap;
        }

        for (Map.Entry entry : theVariables.entrySet()) {
            String varName = entry.getKey();
            ExprVar var = entry.getValue();
            if (var.isExternal()) {
                varsMap.put(varName, new VarInfo(var));
            }
        }

        return varsMap;
    }

    void addFunction(Function func) {

        if (theFunctions == null) {
            theFunctions = new HashMap();
        }

        if (theFunctions.put(func.getName(), func) != null) {
            throw new QueryException(
                "Duplicate declaration for function " + func.getName(), null);
        }
    }

    Function findFunction(String name, int arity) {
        return findFunction(name, arity, false);
    }

    Function findFunction(String name, int arity, boolean local) {

        Function func = null;

        if (local) {
            if (theFunctions == null) {
                return null;
            }

            func = theFunctions.get(name);

        } else {
            StaticContext sctx = this;

            while (func == null && sctx != null) {
                if (sctx.theFunctions != null) {
                    func = sctx.theFunctions.get(name);
                }
                sctx = sctx.theParent;
            }
        }

        if (func != null && !func.isVariadic() && arity != func.getArity()) {
            return null;
        }

        return func;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy