/** * Recursive methods to create a {@link Function} starting from a {@link BinaryExpression} We * consider all possible values of the left and right expressions * * @param pred * @param lookupTable * @return */ private Function getFunction(Expression pred, LookupTable lookupTable) { if (pred instanceof BinaryExpression) { return getFunction((BinaryExpression) pred, lookupTable); } else if (pred instanceof IsNullExpression) { return getFunction((IsNullExpression) pred, lookupTable); } else if (pred instanceof Parenthesis) { Expression inside = ((Parenthesis) pred).getExpression(); return getFunction(inside, lookupTable); } else if (pred instanceof Between) { Between between = (Between) pred; Expression left = between.getLeftExpression(); Expression e1 = between.getBetweenExpressionStart(); Expression e2 = between.getBetweenExpressionEnd(); GreaterThanEquals gte = new GreaterThanEquals(); gte.setLeftExpression(left); gte.setRightExpression(e1); MinorThanEquals mte = new MinorThanEquals(); mte.setLeftExpression(left); mte.setRightExpression(e2); AndExpression ande = new AndExpression(gte, mte); return getFunction(ande, lookupTable); } else if (pred instanceof InExpression) { InExpression inExpr = (InExpression) pred; Expression left = inExpr.getLeftExpression(); ExpressionList ilist = (ExpressionList) inExpr.getRightItemsList(); List<EqualsTo> eqList = new ArrayList<EqualsTo>(); for (Expression item : ilist.getExpressions()) { EqualsTo eq = new EqualsTo(); eq.setLeftExpression(left); eq.setRightExpression(item); eqList.add(eq); } int size = eqList.size(); if (size > 1) { OrExpression or = new OrExpression(eqList.get(size - 1), eqList.get(size - 2)); for (int i = size - 3; i >= 0; i--) { OrExpression orexpr = new OrExpression(eqList.get(i), or); or = orexpr; } return getFunction(or, lookupTable); } else { return getFunction(eqList.get(0), lookupTable); } } else return null; }
public void putLanMatchesOnStack(TermMap left, TermMap right) { EqualsTo eqExpr = new EqualsTo(); // wrap into to_lowercase functions Function funcLeftLower = new Function(); funcLeftLower.setName("LOWER"); funcLeftLower.setParameters(new ExpressionList(Arrays.asList(left.getLiteralValString()))); Function funcRightLower = new Function(); funcRightLower.setName("LOWER"); funcRightLower.setParameters(new ExpressionList(Arrays.asList(right.getLiteralValString()))); eqExpr.setLeftExpression(funcLeftLower); eqExpr.setRightExpression(funcRightLower); tms.push(tmf.createBoolTermMap(eqExpr)); }
private void putArithmeticOnStack( TermMap left, TermMap right, Class<? extends BinaryExpression> arithmeticOp) { try { BinaryExpression arithmetical = arithmeticOp.newInstance(); arithmetical.setLeftExpression(DataTypeHelper.uncast(right.getLiteralValNumeric())); arithmetical.setRightExpression(DataTypeHelper.uncast(left.getLiteralValNumeric())); // for division we always return decimal if (arithmeticOp.equals(Division.class)) { Expression datatype = dth.cast( new StringValue("'" + XSDDatatype.XSDdecimal.getURI() + "'"), dth.getStringCastType()); tms.push(tmf.createNumericalTermMap(arithmetical, datatype)); } else { // determine the datatype if (optConf.isShortcutFilters()) { // check if we can determine the datatype of both parameters Expression dtLeft = DataTypeHelper.uncast(left.getLiteralType()); Expression dtRight = DataTypeHelper.uncast(right.getLiteralType()); if (DataTypeHelper.constantValueExpressions.contains(dtLeft.getClass()) && DataTypeHelper.constantValueExpressions.contains(dtRight.getClass())) { if (dtLeft.toString().equals(dtRight.toString())) { // the same, so we use tms.push(tmf.createNumericalTermMap(arithmetical, dtLeft)); } else { // we just use decimal Expression datatype = dth.cast( new StringValue("'" + XSDDatatype.XSDdecimal.getURI() + "'"), dth.getStringCastType()); tms.push(tmf.createNumericalTermMap(arithmetical, datatype)); } return; } } // it was not possible to short, so create the dynamic datatype expression CaseExpression datatypeCase = new CaseExpression(); WhenClause datatypeEquals = new WhenClause(); EqualsTo datatypesAreEqualwhen = new EqualsTo(); datatypesAreEqualwhen.setLeftExpression(left.getLiteralType()); Expression datatypesEqualThen = left.getLiteralType(); datatypeEquals.setWhenExpression(datatypesAreEqualwhen); datatypeEquals.setThenExpression(datatypesEqualThen); Expression elseDataType = new StringValue("'" + XSDDatatype.XSDdecimal.getURI() + "'"); datatypeCase.setWhenClauses(Arrays.asList((Expression) datatypeEquals)); datatypeCase.setElseExpression(elseDataType); tms.push(tmf.createNumericalTermMap(arithmetical, datatypeCase)); } } catch (InstantiationException | IllegalAccessException e) { log.error("Error creating arithmetic operator", e); } }
@Override public void visit(ExprFunction1 func) { if (func instanceof E_Bound) { TermMap boundCheck = tms.pop(); tms.push(translateIsBound(boundCheck)); } else if (func instanceof E_LogicalNot) { TermMap notCheck = tms.pop(); Expression bool = DataTypeHelper.uncast(notCheck.getLiteralValBool()); if (bool instanceof IsNullExpression) { ((IsNullExpression) bool).setNot(!((IsNullExpression) bool).isNot()); } else { Parenthesis parenthesis = new Parenthesis(bool); parenthesis.setNot(); notCheck = tmf.createBoolTermMap(parenthesis); } tms.push(notCheck); } else if (func instanceof E_Lang) { TermMap langFunc = tms.pop(); Expression lang = DataTypeHelper.uncast(langFunc.getLiteralLang()); TermMap langTermMap = tmf.createStringTermMap(lang); tms.push(langTermMap); } else if (func instanceof E_Str) { TermMap strParam = tms.pop(); // create the coalesce function here List<Expression> strExpressions = new ArrayList<Expression>(); strExpressions.add( dth.cast( DataTypeHelper.uncast(strParam.getLiteralValBinary()), dth.getStringCastType())); strExpressions.add( dth.cast(DataTypeHelper.uncast(strParam.getLiteralValBool()), dth.getStringCastType())); strExpressions.add( dth.cast(DataTypeHelper.uncast(strParam.getLiteralValDate()), dth.getStringCastType())); strExpressions.add( dth.cast( DataTypeHelper.uncast(strParam.getLiteralValNumeric()), dth.getStringCastType())); strExpressions.add( dth.cast( DataTypeHelper.uncast(strParam.getLiteralValString()), dth.getStringCastType())); strExpressions.add(FilterUtil.concat(strParam.getExpressions().toArray(new Expression[0]))); Expression toString = FilterUtil.coalesce(strExpressions.toArray(new Expression[0])); tms.push(tmf.createStringTermMap(toString)); } else if (func instanceof E_IsBlank) { TermMap isBlank = tms.pop(); EqualsTo eq = new EqualsTo(); eq.setLeftExpression(isBlank.getTermType()); eq.setRightExpression(new StringValue("'" + ColumnHelper.COL_VAL_TYPE_BLANK + "'")); tms.push(tmf.createBoolTermMap(eq)); } else if (func instanceof E_IsIRI) { TermMap isIri = tms.pop(); EqualsTo eq = new EqualsTo(); eq.setLeftExpression(isIri.getTermType()); eq.setRightExpression(new StringValue("'" + ColumnHelper.COL_VAL_TYPE_RESOURCE + "'")); tms.push(tmf.createBoolTermMap(eq)); } else if (func instanceof E_IsLiteral) { TermMap isLiteral = tms.pop(); EqualsTo eq = new EqualsTo(); eq.setLeftExpression(isLiteral.getTermType()); eq.setRightExpression(new StringValue("'" + ColumnHelper.COL_VAL_TYPE_LITERAL + "'")); tms.push(tmf.createBoolTermMap(eq)); } else { throw new ImplementationException("Implement Conversion for " + func.toString()); } }
@Override public void visit(EqualsTo et) { Table leftTable = visitSideEquals(et.getLeftExpression()); Table rightTable = visitSideEquals(et.getRightExpression()); _joinTablesExp.addEntry(leftTable, rightTable, et); }