Search in sources :

Example 1 with Array

use of org.teiid.query.sql.symbol.Array in project teiid by teiid.

the class ODataSQLBuilder method buildAggregateQuery.

private void buildAggregateQuery(DocumentNode node, Query outerQuery, ExpandDocumentNode expandResource, OrderBy expandOrder, Query query, EdmNavigationProperty navigationProperty) throws TeiidException {
    Select select = query.getSelect();
    Array array = new Array(Object.class, new ArrayList<Expression>(select.getSymbols()));
    select.getSymbols().clear();
    AggregateSymbol symbol = new AggregateSymbol(AggregateSymbol.Type.ARRAY_AGG.name(), false, array);
    select.addSymbol(symbol);
    symbol.setOrderBy(expandOrder);
    Criteria crit = node.buildJoinCriteria(expandResource, navigationProperty);
    if (crit != null) {
        query.setCriteria(Criteria.combineCriteria(crit, query.getCriteria()));
    }
    // else assertion error?
    expandResource.setColumnIndex(outerQuery.getSelect().getCount() + 1);
    ScalarSubquery agg = new ScalarSubquery(query);
    SubqueryHint subqueryHint = new SubqueryHint();
    subqueryHint.setMergeJoin(true);
    agg.setSubqueryHint(subqueryHint);
    outerQuery.getSelect().addSymbol(agg);
}
Also used : Array(org.teiid.query.sql.symbol.Array) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) ScalarSubquery(org.teiid.query.sql.symbol.ScalarSubquery) Expression(org.teiid.query.sql.symbol.Expression) SubqueryHint(org.teiid.query.sql.lang.ExistsCriteria.SubqueryHint)

Example 2 with Array

use of org.teiid.query.sql.symbol.Array in project teiid by teiid.

the class ExecResolver method findCommandMetadata.

/**
 * @see org.teiid.query.resolver.CommandResolver#findCommandMetadata(org.teiid.query.sql.lang.Command,
 * org.teiid.query.metadata.QueryMetadataInterface)
 */
private void findCommandMetadata(Command command, TempMetadataStore discoveredMetadata, QueryMetadataInterface metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException {
    StoredProcedure storedProcedureCommand = (StoredProcedure) command;
    StoredProcedureInfo storedProcedureInfo = null;
    try {
        storedProcedureInfo = metadata.getStoredProcedureInfoForProcedure(storedProcedureCommand.getProcedureName());
    } catch (QueryMetadataException e) {
        // $NON-NLS-1$
        String[] parts = storedProcedureCommand.getProcedureName().split("\\.", 2);
        if (parts.length > 1 && parts[0].equalsIgnoreCase(metadata.getVirtualDatabaseName())) {
            try {
                storedProcedureInfo = metadata.getStoredProcedureInfoForProcedure(parts[1]);
                storedProcedureCommand.setProcedureName(parts[1]);
            } catch (QueryMetadataException e1) {
            }
        }
        if (storedProcedureInfo == null) {
            throw e;
        }
    }
    storedProcedureCommand.setUpdateCount(storedProcedureInfo.getUpdateCount());
    storedProcedureCommand.setModelID(storedProcedureInfo.getModelID());
    storedProcedureCommand.setProcedureID(storedProcedureInfo.getProcedureID());
    storedProcedureCommand.setProcedureCallableName(storedProcedureInfo.getProcedureCallableName());
    // Get old parameters as they may have expressions set on them - collect
    // those expressions to copy later into the resolved parameters
    Collection<SPParameter> oldParams = storedProcedureCommand.getParameters();
    boolean namedParameters = storedProcedureCommand.displayNamedParameters();
    // of relying on all default values of all optional parameters.
    if (oldParams.size() == 0 || (oldParams.size() == 1 && storedProcedureCommand.isCalledWithReturn())) {
        storedProcedureCommand.setDisplayNamedParameters(true);
        namedParameters = true;
    }
    // Cache original input parameter expressions.  Depending on whether
    // the procedure was parsed with named or unnamed parameters, the keys
    // for this map will either be the String names of the parameters or
    // the Integer indices, as entered in the user query
    Map<Integer, Expression> positionalExpressions = new TreeMap<Integer, Expression>();
    Map<String, Expression> namedExpressions = new TreeMap<String, Expression>(String.CASE_INSENSITIVE_ORDER);
    int adjustIndex = 0;
    for (SPParameter param : oldParams) {
        if (param.getExpression() == null) {
            if (param.getParameterType() == SPParameter.RESULT_SET) {
                // If this was already resolved, just pretend the result set param doesn't exist
                adjustIndex--;
            }
            continue;
        }
        if (namedParameters && param.getParameterType() != SPParameter.RETURN_VALUE) {
            if (namedExpressions.put(param.getParameterSymbol().getShortName(), param.getExpression()) != null) {
                throw new QueryResolverException(QueryPlugin.Event.TEIID30138, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30138, param.getName()));
            }
        } else {
            positionalExpressions.put(param.getIndex() + adjustIndex, param.getExpression());
        }
    }
    storedProcedureCommand.clearParameters();
    int origInputs = positionalExpressions.size() + namedExpressions.size();
    /*
         * Take the values set from the stored procedure implementation, and match up with the
         * types of parameter it is from the metadata and then reset the newly joined parameters
         * into the stored procedure command.  If it is a result set get those columns and place
         * them into the stored procedure command as well.
         */
    List<SPParameter> metadataParams = storedProcedureInfo.getParameters();
    List<SPParameter> clonedMetadataParams = new ArrayList<SPParameter>(metadataParams.size());
    int inputParams = 0;
    int optionalParams = 0;
    int outParams = 0;
    boolean hasReturnValue = false;
    boolean optional = false;
    boolean varargs = false;
    for (int i = 0; i < metadataParams.size(); i++) {
        SPParameter metadataParameter = metadataParams.get(i);
        if ((metadataParameter.getParameterType() == ParameterInfo.IN) || (metadataParameter.getParameterType() == ParameterInfo.INOUT)) {
            if (ResolverUtil.hasDefault(metadataParameter.getMetadataID(), metadata) || metadataParameter.isVarArg()) {
                optional = true;
                optionalParams++;
            } else {
                inputParams++;
                if (optional) {
                    optional = false;
                    inputParams += optionalParams;
                    optionalParams = 0;
                }
            }
            if (metadataParameter.isVarArg()) {
                varargs = true;
            }
        } else if (metadataParameter.getParameterType() == ParameterInfo.OUT) {
            outParams++;
        /*
            	 * TODO: it would consistent to do the following, but it is a breaking change for procedures that have intermixed out params with in.
            	 * we may need to revisit this later
            	 */
        // optional = true;
        // optionalParams++;
        } else if (metadataParameter.getParameterType() == ParameterInfo.RETURN_VALUE) {
            hasReturnValue = true;
        }
        SPParameter clonedParam = (SPParameter) metadataParameter.clone();
        clonedMetadataParams.add(clonedParam);
        storedProcedureCommand.setParameter(clonedParam);
    }
    if (storedProcedureCommand.isCalledWithReturn() && !hasReturnValue) {
        throw new QueryResolverException(QueryPlugin.Event.TEIID30139, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30139, storedProcedureCommand.getGroup()));
    }
    if (!namedParameters && (inputParams > positionalExpressions.size())) {
        // $NON-NLS-1$ //$NON-NLS-2$
        throw new QueryResolverException(QueryPlugin.Event.TEIID30140, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30140, inputParams, inputParams + optionalParams + (varargs ? "+" : ""), origInputs, storedProcedureCommand.getGroup()));
    }
    // Walk through the resolved parameters and set the expressions from the
    // input parameters
    int exprIndex = 1;
    HashSet<String> expected = new HashSet<String>();
    if (storedProcedureCommand.isCalledWithReturn() && hasReturnValue) {
        for (SPParameter param : clonedMetadataParams) {
            if (param.getParameterType() == SPParameter.RETURN_VALUE) {
                Expression expr = positionalExpressions.remove(exprIndex++);
                param.setExpression(expr);
                break;
            }
        }
    }
    for (SPParameter param : clonedMetadataParams) {
        if (param.getParameterType() == SPParameter.RESULT_SET || param.getParameterType() == SPParameter.RETURN_VALUE) {
            continue;
        }
        if (namedParameters) {
            String nameKey = param.getParameterSymbol().getShortName();
            Expression expr = namedExpressions.remove(nameKey);
            // With named parameters, have to check on optional params and default values
            if (expr == null) {
                if (param.getParameterType() != ParameterInfo.OUT) {
                    param.setUsingDefault(true);
                    expected.add(nameKey);
                    if (!param.isVarArg()) {
                        expr = ResolverUtil.getDefault(param.getParameterSymbol(), metadata);
                    } else {
                        // zero length array
                        List<Expression> exprs = new ArrayList<Expression>(0);
                        Array array = new Array(exprs);
                        array.setImplicit(true);
                        array.setType(param.getClassType());
                        expr = array;
                    }
                }
            }
            param.setExpression(expr);
        } else {
            Expression expr = positionalExpressions.remove(exprIndex++);
            if (param.getParameterType() == SPParameter.OUT) {
                if (expr != null) {
                    boolean isRef = expr instanceof Reference;
                    if (!isRef || exprIndex <= inputParams + 1) {
                        // for backwards compatibility, this should be treated instead as an input
                        exprIndex--;
                        positionalExpressions.put(exprIndex, expr);
                    } else if (isRef) {
                        // mimics the hack that was in PreparedStatementRequest.
                        Reference ref = (Reference) expr;
                        // may be an out
                        ref.setOptional(true);
                    /*
	                		 * Note that there is a corner case here with out parameters intermixed with optional parameters
	                		 * there's not a good way around this.
	                		 */
                    }
                }
                continue;
            }
            if (expr == null) {
                if (!param.isVarArg()) {
                    expr = ResolverUtil.getDefault(param.getParameterSymbol(), metadata);
                }
                param.setUsingDefault(true);
            }
            if (param.isVarArg()) {
                List<Expression> exprs = new ArrayList<Expression>(positionalExpressions.size() + 1);
                if (expr != null) {
                    exprs.add(expr);
                }
                exprs.addAll(positionalExpressions.values());
                positionalExpressions.clear();
                Array array = new Array(exprs);
                array.setImplicit(true);
                array.setType(param.getClassType());
                expr = array;
            }
            param.setExpression(expr);
        }
    }
    // Check for leftovers, i.e. params entered by user w/ wrong/unknown names
    if (!namedExpressions.isEmpty()) {
        throw new QueryResolverException(QueryPlugin.Event.TEIID30141, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30141, namedExpressions.keySet(), expected));
    }
    if (!positionalExpressions.isEmpty()) {
        throw new QueryResolverException(QueryPlugin.Event.TEIID31113, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31113, positionalExpressions.size(), origInputs, storedProcedureCommand.getGroup().toString()));
    }
    // Create temporary metadata that defines a group based on either the stored proc
    // name or the stored query name - this will be used later during planning
    String procName = storedProcedureCommand.getProcedureName();
    List tempElements = storedProcedureCommand.getProjectedSymbols();
    boolean isVirtual = storedProcedureInfo.getQueryPlan() != null;
    discoveredMetadata.addTempGroup(procName, tempElements, isVirtual);
    // Resolve tempElements against new metadata
    GroupSymbol procGroup = new GroupSymbol(storedProcedureInfo.getProcedureCallableName());
    procGroup.setProcedure(true);
    TempMetadataID tid = discoveredMetadata.getTempGroupID(procName);
    tid.setOriginalMetadataID(storedProcedureCommand.getProcedureID());
    procGroup.setMetadataID(tid);
    storedProcedureCommand.setGroup(procGroup);
}
Also used : SPParameter(org.teiid.query.sql.lang.SPParameter) Reference(org.teiid.query.sql.symbol.Reference) ArrayList(java.util.ArrayList) TempMetadataID(org.teiid.query.metadata.TempMetadataID) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) TreeMap(java.util.TreeMap) QueryResolverException(org.teiid.api.exception.query.QueryResolverException) StoredProcedureInfo(org.teiid.query.metadata.StoredProcedureInfo) Array(org.teiid.query.sql.symbol.Array) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 3 with Array

use of org.teiid.query.sql.symbol.Array in project teiid by teiid.

the class LanguageBridgeFactory method translate.

org.teiid.language.Comparison translate(DependentSetCriteria criteria) {
    Operator operator = Operator.EQ;
    org.teiid.language.Expression arg = null;
    final TupleBuffer tb = criteria.getDependentValueSource().getTupleBuffer();
    if (criteria.getValueExpression() instanceof Array) {
        Array array = (Array) criteria.getValueExpression();
        List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>();
        Class<?> baseType = null;
        for (Expression ex : array.getExpressions()) {
            if (baseType == null) {
                baseType = ex.getType();
            } else if (!baseType.equals(ex.getType())) {
                baseType = DataTypeManager.DefaultDataClasses.OBJECT;
            }
            params.add(createParameter(criteria, tb, ex));
        }
        arg = new org.teiid.language.Array(baseType, params);
    } else {
        Expression ex = criteria.getValueExpression();
        arg = createParameter(criteria, tb, ex);
    }
    if (this.dependentSets == null) {
        this.dependentSets = new HashMap<String, List<? extends List<?>>>();
    }
    this.dependentSets.put(criteria.getContextSymbol(), new TupleBufferList(tb));
    Comparison result = new org.teiid.language.Comparison(translate(criteria.getExpression()), arg, operator);
    return result;
}
Also used : Operator(org.teiid.language.Comparison.Operator) TupleBuffer(org.teiid.common.buffer.TupleBuffer) org.teiid.language(org.teiid.language) Array(org.teiid.query.sql.symbol.Array) SearchedCaseExpression(org.teiid.query.sql.symbol.SearchedCaseExpression) Expression(org.teiid.query.sql.symbol.Expression)

Example 4 with Array

use of org.teiid.query.sql.symbol.Array in project teiid by teiid.

the class TestProcedureResolving method testVarArgs.

@Test
public void testVarArgs() throws Exception {
    String ddl = "create foreign procedure proc (x integer, VARIADIC z integer) returns (x string);\n";
    TransformationMetadata tm = createMetadata(ddl);
    // $NON-NLS-1$
    String sql = "call proc (1, 2, 3)";
    StoredProcedure sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
    assertEquals("EXEC proc(1, 2, 3)", sp.toString());
    assertEquals(new Constant(1), sp.getParameter(1).getExpression());
    assertEquals(new Array(DataTypeManager.DefaultDataClasses.INTEGER, Arrays.asList((Expression) new Constant(2), new Constant(3))), sp.getParameter(2).getExpression());
    assertEquals(SPParameter.RESULT_SET, sp.getParameter(3).getParameterType());
    // $NON-NLS-1$
    sql = "call proc (1)";
    sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
    assertEquals("EXEC proc(1)", sp.toString());
    assertEquals(new Array(DataTypeManager.DefaultDataClasses.INTEGER, new ArrayList<Expression>(0)), sp.getParameter(2).getExpression());
    sp = (StoredProcedure) QueryRewriter.evaluateAndRewrite(sp, new Evaluator(null, null, null), null, tm);
    LanguageBridgeFactory lbf = new LanguageBridgeFactory(tm);
    Call call = (Call) lbf.translate(sp);
    assertEquals("EXEC proc(1)", call.toString());
    // $NON-NLS-1$
    sql = "call proc (1, (2, 3))";
    sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
    assertEquals("EXEC proc(1, (2, 3))", sp.toString());
    assertEquals(new Constant(1), sp.getParameter(1).getExpression());
    assertEquals(new Array(DataTypeManager.DefaultDataClasses.INTEGER, Arrays.asList((Expression) new Constant(2), new Constant(3))), sp.getParameter(2).getExpression());
    assertEquals(SPParameter.RESULT_SET, sp.getParameter(3).getParameterType());
}
Also used : Array(org.teiid.query.sql.symbol.Array) Call(org.teiid.language.Call) TransformationMetadata(org.teiid.query.metadata.TransformationMetadata) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) Evaluator(org.teiid.query.eval.Evaluator) LanguageBridgeFactory(org.teiid.dqp.internal.datamgr.LanguageBridgeFactory) Test(org.junit.Test)

Example 5 with Array

use of org.teiid.query.sql.symbol.Array in project teiid by teiid.

the class TestProcedureResolving method testVarArgs2.

@Test
public void testVarArgs2() throws Exception {
    String ddl = "create foreign procedure proc (VARIADIC z object) returns (x string);\n";
    TransformationMetadata tm = createMetadata(ddl);
    // $NON-NLS-1$
    String sql = "call proc ()";
    StoredProcedure sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
    assertEquals("EXEC proc()", sp.toString());
    assertEquals(new Array(DataTypeManager.DefaultDataClasses.OBJECT, new ArrayList<Expression>(0)), sp.getParameter(1).getExpression());
    // $NON-NLS-1$
    sql = "call proc (1, (2, 3))";
    sp = (StoredProcedure) TestResolver.helpResolve(sql, tm);
    assertEquals("EXEC proc(1, (2, 3))", sp.toString());
    ArrayList<Expression> expressions = new ArrayList<Expression>();
    expressions.add(new Constant(1));
    expressions.add(new Array(DataTypeManager.DefaultDataClasses.INTEGER, Arrays.asList((Expression) new Constant(2), new Constant(3))));
    assertEquals(new Array(DataTypeManager.DefaultDataClasses.OBJECT, expressions), sp.getParameter(1).getExpression());
}
Also used : Array(org.teiid.query.sql.symbol.Array) TransformationMetadata(org.teiid.query.metadata.TransformationMetadata) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) Expression(org.teiid.query.sql.symbol.Expression) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

Array (org.teiid.query.sql.symbol.Array)14 Expression (org.teiid.query.sql.symbol.Expression)9 ArrayList (java.util.ArrayList)6 Test (org.junit.Test)5 Constant (org.teiid.query.sql.symbol.Constant)5 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)4 ArrayImpl (org.teiid.core.types.ArrayImpl)3 TransformationMetadata (org.teiid.query.metadata.TransformationMetadata)3 LanguageBridgeFactory (org.teiid.dqp.internal.datamgr.LanguageBridgeFactory)2 Call (org.teiid.language.Call)2 Evaluator (org.teiid.query.eval.Evaluator)2 CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)2 Criteria (org.teiid.query.sql.lang.Criteria)2 DependentSetCriteria (org.teiid.query.sql.lang.DependentSetCriteria)2 Reference (org.teiid.query.sql.symbol.Reference)2 HashSet (java.util.HashSet)1 List (java.util.List)1 TreeMap (java.util.TreeMap)1 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)1 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)1