use of org.teiid.query.sql.symbol.Function in project teiid by teiid.
the class RuleAssignOutputElements method pushProjection.
private boolean pushProjection(PlanNode node, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, Set<Expression> requiredSymbols, PlanNode accessParent, PlanNode accessNode, Expression ss) throws QueryMetadataException, TeiidComponentException {
if (finalRun && accessParent == null) {
Expression ex = SymbolMap.getExpression(ss);
if (ex instanceof ElementSymbol || ex instanceof Constant) {
return false;
}
Object modelId = null;
if (accessNode != null) {
modelId = RuleRaiseAccess.getModelIDFromAccess(accessNode, metadata);
// narrow check for projection pushing
if (RuleRaiseAccess.canPushSymbol(ss, true, modelId, metadata, capFinder, null)) {
requiredSymbols.add(ss);
return true;
}
}
if (NodeEditor.findNodePreOrder(node, NodeConstants.Types.GROUP, NodeConstants.Types.ACCESS) == null) {
Collection<Function> functions = FunctionCollectorVisitor.getFunctions(ss, false);
List<Function> mustPushSubexpression = null;
for (Function function : functions) {
if (function.getFunctionDescriptor().getPushdown() != PushDown.MUST_PUSHDOWN || (EvaluatableVisitor.willBecomeConstant(function) && accessNode != null && CapabilitiesUtil.supports(Capability.SELECT_WITHOUT_FROM, modelId, metadata, capFinder))) {
continue;
}
// TODO: we could try to get something in between everything and just the partial
if (accessNode != null && RuleRaiseAccess.canPushSymbol(function, true, modelId, metadata, capFinder, null)) {
if (mustPushSubexpression == null) {
mustPushSubexpression = new ArrayList<Function>();
}
mustPushSubexpression.add(function);
continue;
}
// assume we need the whole thing
requiredSymbols.add(ss);
checkSymbols = true;
return true;
}
if (mustPushSubexpression != null) {
requiredSymbols.addAll(mustPushSubexpression);
}
}
}
return false;
}
use of org.teiid.query.sql.symbol.Function in project teiid by teiid.
the class RulePushLimit method op.
static Expression op(String op, Expression expr1, Expression expr2, FunctionLibrary functionLibrary) {
if (expr1 == null) {
return expr2;
}
if (expr2 == null) {
return expr1;
}
Function newExpr = new Function(op, new Expression[] { expr1, expr2 });
newExpr.setFunctionDescriptor(functionLibrary.findFunction(op, new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER }));
newExpr.setType(newExpr.getFunctionDescriptor().getReturnType());
return evaluateIfPossible(newExpr);
}
use of org.teiid.query.sql.symbol.Function in project teiid by teiid.
the class RecordTable method matchesPkColumn.
@Override
public Boolean matchesPkColumn(int pkIndex, Expression ex) {
if (ex instanceof Function) {
Function f = (Function) ex;
ex = f.getArg(0);
}
return (pkColumns[pkIndex].equals(ex));
}
use of org.teiid.query.sql.symbol.Function in project teiid by teiid.
the class BaseIndexInfo method processCriteria.
private void processCriteria(Criteria condition, boolean primary) {
List<Criteria> crits = Criteria.separateCriteriaByAnd(condition);
if (!primary) {
for (Iterator<Criteria> critIter = crits.iterator(); critIter.hasNext(); ) {
Criteria criteria = critIter.next();
if (table.getColumnMap().keySet().containsAll(ElementCollectorVisitor.getElements(criteria, false))) {
if (coveredCriteria == null) {
coveredCriteria = new CompoundCriteria();
}
coveredCriteria.addCriteria(criteria);
} else {
covering = false;
if (nonCoveredCriteria == null) {
nonCoveredCriteria = new CompoundCriteria();
}
nonCoveredCriteria.addCriteria(criteria);
critIter.remove();
}
}
}
for (int i = 0; i < table.getPkLength(); i++) {
for (Iterator<Criteria> critIter = crits.iterator(); critIter.hasNext(); ) {
Criteria criteria = critIter.next();
if (criteria instanceof CompareCriteria) {
CompareCriteria cc = (CompareCriteria) criteria;
Object matchResult = table.matchesPkColumn(i, cc.getLeftExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
if (cc.getOperator() != CompareCriteria.EQ && !table.supportsOrdering(i, cc.getLeftExpression())) {
critIter.remove();
continue;
}
this.addCondition(i, matchResult, (Constant) cc.getRightExpression(), cc.getOperator());
critIter.remove();
} else if (criteria instanceof IsNullCriteria) {
IsNullCriteria inc = (IsNullCriteria) criteria;
Object matchResult = table.matchesPkColumn(i, inc.getExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
this.addCondition(i, matchResult, new Constant(null), CompareCriteria.EQ);
critIter.remove();
} else if (criteria instanceof MatchCriteria) {
MatchCriteria matchCriteria = (MatchCriteria) criteria;
Object matchResult = table.matchesPkColumn(i, matchCriteria.getLeftExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
Constant value = (Constant) matchCriteria.getRightExpression();
String pattern = (String) value.getValue();
boolean escaped = false;
char escapeChar = matchCriteria.getEscapeChar();
if (matchCriteria.getMode() == MatchMode.REGEX) {
escapeChar = '\\';
}
StringBuilder prefix = new StringBuilder();
if (pattern.length() > 0 && matchCriteria.getMode() == MatchMode.REGEX && pattern.charAt(0) != '^') {
// make the assumption that we require an anchor
continue;
}
for (int j = matchCriteria.getMode() == MatchMode.REGEX ? 1 : 0; j < pattern.length(); j++) {
char character = pattern.charAt(j);
if (character == escapeChar && character != MatchCriteria.NULL_ESCAPE_CHAR) {
if (escaped) {
prefix.append(character);
escaped = false;
} else {
escaped = true;
}
continue;
}
if (!escaped) {
if (matchCriteria.getMode() == MatchMode.LIKE) {
if (character == MatchCriteria.WILDCARD_CHAR || character == MatchCriteria.MATCH_CHAR) {
break;
}
} else {
int index = Arrays.binarySearch(Evaluator.REGEX_RESERVED, character);
if (index >= 0 && pattern.length() > 0) {
getRegexPrefix(pattern, escapeChar, prefix, j, character);
break;
}
}
} else {
escaped = false;
}
prefix.append(character);
}
if (prefix.length() > 0) {
this.addCondition(i, matchResult, new Constant(prefix.toString()), CompareCriteria.GE);
if (matchCriteria.getLeftExpression() instanceof Function && table.supportsOrdering(i, matchCriteria.getLeftExpression())) {
// this comparison needs to be aware of case
this.addCondition(i, matchResult, new Constant(prefix.substring(0, prefix.length() - 1) + (char) (Character.toLowerCase(prefix.charAt(prefix.length() - 1)) + 1)), CompareCriteria.LE);
} else {
this.addCondition(i, matchResult, new Constant(prefix.substring(0, prefix.length() - 1) + (char) (prefix.charAt(prefix.length() - 1) + 1)), CompareCriteria.LE);
}
} else {
critIter.remove();
}
} else if (criteria instanceof SetCriteria) {
SetCriteria setCriteria = (SetCriteria) criteria;
if (setCriteria.isNegated()) {
continue;
}
Object matchResult = table.matchesPkColumn(i, setCriteria.getExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
Collection<Constant> values = (Collection<Constant>) setCriteria.getValues();
this.addSet(i, matchResult, values);
critIter.remove();
}
}
}
}
use of org.teiid.query.sql.symbol.Function in project teiid by teiid.
the class TestDDLStringVisitor method testForeignTable.
@Test
public void testForeignTable() throws Exception {
String ddl = "SET NAMESPACE 'http://www.teiid.org/ext/relational/2012' AS teiid_rel;\n\nCREATE FOREIGN TABLE G1 (\n" + " e1 integer,\n" + " e2 string(10),\n" + " e3 date NOT NULL DEFAULT current_date() OPTIONS (\"teiid_rel:default_handling\" 'expression'),\n" + " e4 bigdecimal(12,3),\n" + " e5 integer AUTO_INCREMENT OPTIONS (UUID 'uuid', NAMEINSOURCE 'nis', SELECTABLE FALSE),\n" + " e6 string DEFAULT 'hello',\n" + " PRIMARY KEY(e1),\n" + " UNIQUE(e2),\n" + " UNIQUE(e3),\n" + " INDEX(e5),\n" + " INDEX(e6)\n" + ") OPTIONS (ANNOTATION 'Test Table', CARDINALITY '12', FOO 'BAR', UPDATABLE 'true', UUID 'uuid2');";
MetadataFactory mf = new MetadataFactory("test", 1, "model", TestDDLParser.getDataTypes(), new Properties(), null);
Table table = mf.addTable("G1");
table.setVirtual(false);
mf.addColumn("e1", "integer", table);
Column e2 = mf.addColumn("e2", "varchar", table);
e2.setLength(10);
Column e3 = mf.addColumn("e3", "date", table);
e3.setNullType(NullType.No_Nulls);
SQLParserUtil.setDefault(e3, new Function("current_date", new Expression[0]));
Column e4 = mf.addColumn("e4", "decimal", table);
e4.setPrecision(12);
e4.setScale(3);
Column e5 = mf.addColumn("e5", "integer", table);
e5.setAutoIncremented(true);
e5.setUUID("uuid");
e5.setNameInSource("nis");
e5.setSelectable(false);
Column e6 = mf.addColumn("e6", "varchar", table);
e6.setDefaultValue("hello");
mf.addPrimaryKey("PK", Arrays.asList("e1"), table);
mf.addIndex("UNIQUE0", false, Arrays.asList("e2"), table);
mf.addIndex("UNIQUE1", false, Arrays.asList("e3"), table);
mf.addIndex("INDEX0", true, Arrays.asList("e5"), table);
mf.addIndex("INDEX1", true, Arrays.asList("e6"), table);
Map<String, String> options = new HashMap<String, String>();
options.put("CARDINALITY", "12");
options.put("UUID", "uuid2");
options.put("UPDATABLE", "true");
options.put("FOO", "BAR");
options.put("ANNOTATION", "Test Table");
table.setProperties(options);
String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null);
assertEquals(ddl, metadataDDL);
}
Aggregations