protected static String processFuncSet(Formatter formatter, FunctionCall node) { StringBuilder builder = new StringBuilder(); String functionName = getFunctionName(node); int numArguments = node.getArguments().size(); builder.append(functionName).append('(').append(formatter.process(node.getArguments().get(0), null)).append( ')'); if (numArguments > 1) { builder.append(" ON "); } for (int i = 1; i < numArguments; i++) { Expression item = node.getArguments().get(i); if (i == 1) { builder.append(formatter.process(item, null)); } else { builder.append(", ").append(formatter.process(item, null)); } } return builder.toString(); }
@Override protected String visitArithmeticExpression(ArithmeticExpression node, Void context) { if (node.getType().equals(ArithmeticExpression.Type.DIVIDE)) { if (_outputDivideByZeroGuard == true) { if (node.getRight() instanceof FunctionCall) { if (getFunctionName((FunctionCall) node.getRight()).equals("nullifzero")) { // bypass appending nullifzero return formatBinaryExpression(node.getType().getValue(), node.getLeft(), node.getRight()); } } else if (node.getRight() instanceof Literal) { // purely literal return formatBinaryExpression(node.getType().getValue(), node.getLeft(), node.getRight()); } List<Expression> arguments = new ArrayList<Expression>(); arguments.add(node.getRight()); FunctionCall nullifzeroFunc = new FunctionCall(new QualifiedName("nullifzero"), arguments); return formatBinaryExpression(node.getType().getValue(), node.getLeft(), nullifzeroFunc); } else { return formatBinaryExpression(node.getType().getValue(), node.getLeft(), node.getRight()); } } else { return formatBinaryExpression(node.getType().getValue(), node.getLeft(), node.getRight()); } }
protected String joinPassExpressions(String on, List<Expression> expressions) { return Joiner.on(on).join(transform(expressions, new Function<Expression, Object>() { @Override public Object apply(Expression input) { if (input instanceof QualifiedNameReference) { // 20150709: enclose vero ident in () in case association matters return '(' + process(input, null) + ')'; } else { return process(input, null); } } })); }
public static void printExpression(String sql) { println(sql.trim()); println(""); System.out.println("EXP Printing CommonTree toString..."); CommonTree tree = VeroSqlParser.parseExpression(sql); println(TreePrinter.treeToString(tree)); println(""); System.out.println("EXP Printing AST toString..."); Expression expression = VeroSqlParser.createExpression(tree); println(expression.toString()); println(""); System.out.println("EXP Printing Format sql toString..."); // TODO: support formatting all statement types println(FormatterFactory.getSqlFormatter().formatSql(expression)); println(""); println(repeat("=", 60)); println(""); }
@Override protected Void visitValues(Values node, Integer indent) { builder.append(" VALUES "); boolean first = true; for (Expression row : node.getRows()) { builder.append("\n") .append(indentString(indent)) .append(first ? " " : ", "); builder.append(formatExpression(row, parameters, indent)); first = false; } builder.append('\n'); return null; }
/** * Parses the list with values to insert and returns them as Objects */ @Override public List<Object> visitValues(Values values, QueryState state){ List<Object> result = new ArrayList<Object>(); for(Expression rowExpression : values.getRows()){ if(rowExpression instanceof Row) { Row row = (Row)rowExpression; for(Expression rowValue : row.getItems()){ if(!(rowValue instanceof Literal)) { state.addException("Unable to parse non-literal value : "+rowValue); return result; } result.add(getObject((Literal)rowValue)); } }else if (rowExpression instanceof Literal){ result.add(getObject((Literal)rowExpression)); }else { state.addException("Unknown VALUES type "+rowExpression.getClass()+" encountered"); return null; } } return result; }
@Override public PlanNode visitSample(SampleNode node, RewriteContext<Void> context) { if (node.getSampleType() == SampleNode.Type.BERNOULLI) { PlanNode rewrittenSource = context.rewrite(node.getSource()); ComparisonExpression expression = new ComparisonExpression( ComparisonExpression.Type.LESS_THAN, new FunctionCall(QualifiedName.of("rand"), ImmutableList.<Expression>of()), new DoubleLiteral(Double.toString(node.getSampleRatio()))); return new FilterNode(node.getId(), rewrittenSource, expression); } else if (node.getSampleType() == SampleNode.Type.POISSONIZED || node.getSampleType() == SampleNode.Type.SYSTEM) { return context.defaultRewrite(node); } throw new UnsupportedOperationException("not yet implemented"); }
@Test public void testFromIsNullPredicate() throws Exception { Expression originalExpression = isNull(A); ExtractionResult result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(A, Domain.onlyNull(BIGINT)))); originalExpression = isNull(K); result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(K, Domain.onlyNull(HYPER_LOG_LOG)))); originalExpression = not(isNull(A)); result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(A, Domain.notNull(BIGINT)))); originalExpression = not(isNull(K)); result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(K, Domain.notNull(HYPER_LOG_LOG)))); }
private OperatorFactory compileFilterWithNoInputColumns(Expression filter, ExpressionCompiler compiler) { filter = ExpressionTreeRewriter.rewriteWith(new SymbolToInputRewriter(ImmutableMap.<Symbol, Integer>of()), filter); IdentityHashMap<Expression, Type> expressionTypes = getExpressionTypesFromInput(TEST_SESSION, metadata, SQL_PARSER, INPUT_TYPES, ImmutableList.of(filter)); try { PageProcessor processor = compiler.compilePageProcessor(toRowExpression(filter, expressionTypes), ImmutableList.of()); return new FilterAndProjectOperator.FilterAndProjectOperatorFactory(0, new PlanNodeId("test"), processor, ImmutableList.<Type>of()); } catch (Throwable e) { if (e instanceof UncheckedExecutionException) { e = e.getCause(); } throw new RuntimeException("Error compiling " + filter + ": " + e.getMessage(), e); } }
public InterpretedFilterFunction( Expression predicate, Map<Symbol, Type> symbolTypes, Map<Symbol, Integer> symbolToInputMappings, Metadata metadata, SqlParser sqlParser, Session session) { // pre-compute symbol -> input mappings and replace the corresponding nodes in the tree Expression rewritten = ExpressionTreeRewriter.rewriteWith(new SymbolToInputRewriter(symbolToInputMappings), predicate); // analyze expression so we can know the type of every expression in the tree ImmutableMap.Builder<Integer, Type> inputTypes = ImmutableMap.builder(); for (Map.Entry<Symbol, Integer> entry : symbolToInputMappings.entrySet()) { inputTypes.put(entry.getValue(), symbolTypes.get(entry.getKey())); } IdentityHashMap<Expression, Type> expressionTypes = getExpressionTypesFromInput(session, metadata, sqlParser, inputTypes.build(), rewritten); evaluator = ExpressionInterpreter.expressionInterpreter(rewritten, metadata, session, expressionTypes); }
@Override public PlanNode visitTableScan(TableScanNode node, RewriteContext<Void> context) { Expression originalConstraint = null; if (node.getOriginalConstraint() != null) { originalConstraint = canonicalizeExpression(node.getOriginalConstraint()); } return new TableScanNode( node.getId(), node.getTable(), node.getOutputSymbols(), node.getAssignments(), node.getLayout(), node.getCurrentConstraint(), originalConstraint); }
@Override public Void visitProject(ProjectNode node, Void context) { StringBuilder builder = new StringBuilder(); for (Map.Entry<Symbol, Expression> entry : node.getAssignments().entrySet()) { if ((entry.getValue() instanceof QualifiedNameReference) && ((QualifiedNameReference) entry.getValue()).getName().equals(entry.getKey().toQualifiedName())) { // skip identity assignments continue; } builder.append(format("%s := %s\\n", entry.getKey(), entry.getValue())); } printNode(node, "Project", builder.toString(), NODE_COLORS.get(NodeType.PROJECT)); return node.getSource().accept(this, context); }
private Expression rewriteExpression(Expression expression, Predicate<Symbol> symbolScope, boolean allowFullReplacement) { Iterable<Expression> subExpressions = SubExpressionExtractor.extract(expression); if (!allowFullReplacement) { subExpressions = filter(subExpressions, not(equalTo(expression))); } ImmutableMap.Builder<Expression, Expression> expressionRemap = ImmutableMap.builder(); for (Expression subExpression : subExpressions) { Expression canonical = getScopedCanonical(subExpression, symbolScope); if (canonical != null) { expressionRemap.put(subExpression, canonical); } } // Perform a naive single-pass traversal to try to rewrite non-compliant portions of the tree. Prefers to replace // larger subtrees over smaller subtrees // TODO: this rewrite can probably be made more sophisticated Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ExpressionNodeInliner(expressionRemap.build()), expression); if (!symbolToExpressionPredicate(symbolScope).apply(rewritten)) { // If the rewritten is still not compliant with the symbol scope, just give up return null; } return rewritten; }
@Override protected Type visitInPredicate(InPredicate node, StackableAstVisitorContext<AnalysisContext> context) { Expression value = node.getValue(); process(value, context); Expression valueList = node.getValueList(); process(valueList, context); if (valueList instanceof InListExpression) { InListExpression inListExpression = (InListExpression) valueList; coerceToSingleType(context, "IN value and list items must be the same type: %s", ImmutableList.<Expression>builder().add(value).addAll(inListExpression.getValues()).build()); } else if (valueList instanceof SubqueryExpression) { coerceToSingleType(context, node, "value and result of subquery must be of the same type for IN expression: %s vs %s", value, valueList); } expressionTypes.put(node, BOOLEAN); return BOOLEAN; }
@Override public Boolean visitWindowFrame(WindowFrame node, Void context) { Optional<Expression> start = node.getStart().getValue(); if (start.isPresent()) { if (!process(start.get(), context)) { throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, start.get(), "Window frame start must be an aggregate expression or appear in GROUP BY clause"); } } if (node.getEnd().isPresent() && node.getEnd().get().getValue().isPresent()) { Expression endValue = node.getEnd().get().getValue().get(); if (!process(endValue, context)) { throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, endValue, "Window frame end must be an aggregate expression or appear in GROUP BY clause"); } } return true; }
@Test public void testFromIsNotNullPredicate() throws Exception { Expression originalExpression = isNotNull(A); ExtractionResult result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(A, Domain.notNull(BIGINT)))); originalExpression = isNotNull(K); result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(K, Domain.notNull(HYPER_LOG_LOG)))); originalExpression = not(isNotNull(A)); result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(A, Domain.onlyNull(BIGINT)))); originalExpression = not(isNotNull(K)); result = fromPredicate(originalExpression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertEquals(result.getTupleDomain(), withColumnDomains(ImmutableMap.of(K, Domain.onlyNull(HYPER_LOG_LOG)))); }
@Override public Void visitProject(ProjectNode node, Void context) { PlanNode source = node.getSource(); source.accept(this, context); // visit child verifyUniqueId(node); Set<Symbol> inputs = ImmutableSet.copyOf(source.getOutputSymbols()); for (Expression expression : node.getAssignments().values()) { Set<Symbol> dependencies = DependencyExtractor.extractUnique(expression); checkDependencies(inputs, dependencies, "Invalid node. Expression dependencies (%s) not in source plan output (%s)", dependencies, inputs); } return null; }
protected static String processFuncAtan2(Formatter formatter, FunctionCall node) { Expression x = node.getArguments().get(0); Expression y = node.getArguments().get(1); FunctionCall xx = new FunctionCall(new QualifiedName("power"), Arrays.asList(x, new LongLiteral("2"))); FunctionCall yy = new FunctionCall(new QualifiedName("power"), Arrays.asList(y, new LongLiteral("2"))); ArithmeticExpression xxAddyy = new ArithmeticExpression(ArithmeticExpression.Type.ADD, xx, yy); FunctionCall sqrt_xxAddyy = new FunctionCall(new QualifiedName("sqrt"), Arrays.asList(xxAddyy)); ArithmeticExpression substract = new ArithmeticExpression(ArithmeticExpression.Type.SUBTRACT, sqrt_xxAddyy, x); ArithmeticExpression divide = new ArithmeticExpression(ArithmeticExpression.Type.DIVIDE, substract, y); FunctionCall arctan = new FunctionCall(new QualifiedName("atan"), Arrays.asList(divide)); ArithmeticExpression multiply = new ArithmeticExpression(ArithmeticExpression.Type.MULTIPLY, new DoubleLiteral("2"), arctan); return formatter.process(multiply, null); }
protected static String processFuncNullifzero(Formatter formatter, FunctionCall node) { Expression x = node.getArguments().get(0); List<WhenClause> listWhen = new ArrayList<WhenClause>(); ComparisonExpression ce = new ComparisonExpression(ComparisonExpression.Type.EQUAL, x, new LongLiteral("0")); WhenClause wc = new WhenClause(ce, new NullLiteral()); listWhen.add(wc); SearchedCaseExpression sce = new SearchedCaseExpression(listWhen, x); return formatter.process(sce, null); }
protected static Expression processFuncLast(ComparisonExpression node) { System.out.println("Processing last()"); Expression rightNode = node.getRight(); Expression leftNode = node.getLeft(); FunctionCall last = (FunctionCall) rightNode; // # of arguments are already checked outside 1 or 2 String number = last.getArguments().get(0).toString(); String format = "DAY"; // default if (last.getArguments().size() == 2) { format = last.getArguments().get(1).toString().replaceAll("\"", ""); } IntervalLiteral.Sign sign; if (number.startsWith("-")) { sign = IntervalLiteral.Sign.NEGATIVE; number = number.substring(1); } else { sign = IntervalLiteral.Sign.POSITIVE; } CurrentTime cTime = new CurrentTime(CurrentTime.Type.DATE); IntervalLiteral interval = new IntervalLiteral(number, sign, format); ArithmeticExpression arithmOp = new ArithmeticExpression(ArithmeticExpression.Type.SUBTRACT, cTime, interval); BetweenPredicate bPredicate = new BetweenPredicate(leftNode, arithmOp, cTime); return bPredicate; }
public Function<Expression, String> expressionFormatterFunction() { return new Function<Expression, String>() { @Override public String apply(Expression input) { return formatExpression(input); } }; }
@Override protected String visitArrayConstructor(ArrayConstructor node, Void context) { ImmutableList.Builder<String> valueStrings = ImmutableList.builder(); for (Expression value : node.getValues()) { valueStrings.add(sqlFormatter.formatSql(value)); } return "ARRAY[" + Joiner.on(",").join(valueStrings.build()) + "]"; }
protected String formatBinaryExpression(String operator, Expression left, Expression right) { if (operator.equals("")) { // 20150709: +VPC+ return process(left, null) + process(right, null); } else { return '(' + process(left, null) + ' ' + operator + ' ' + process(right, null) + ')'; } }
protected String joinExpressions(List<Expression> expressions) { return Joiner.on(", ").join(transform(expressions, new Function<Expression, Object>() { @Override public Object apply(Expression input) { return process(input, null); } })); }
protected String joinExpressions(String on, List<Expression> expressions) { return Joiner.on(on).join(transform(expressions, new Function<Expression, Object>() { @Override public Object apply(Expression input) { return process(input, null); } })); }
@Override protected String visitArrayConstructor(ArrayConstructor node, StackableAstVisitorContext<Integer> indent) { ImmutableList.Builder<String> valueStrings = ImmutableList.builder(); for (Expression value : node.getValues()) { valueStrings.add(formatExpression(value, parameters, indent.getContext() + 1)); } return "ARRAY[" + Joiner.on(",").join(valueStrings.build()) + "]"; }