/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jena.sdb.core.sqlnode; import java.util.Collection; import java.util.List; import org.apache.jena.atlas.io.IndentedWriter; import org.apache.jena.sdb.core.Annotations ; import org.apache.jena.sdb.core.sqlexpr.SqlColumn ; import org.apache.jena.sdb.core.sqlexpr.SqlExpr ; import org.apache.jena.sdb.core.sqlexpr.SqlExprList ; import org.apache.jena.sparql.core.Var ; public class SqlNodeTextVisitor implements SqlNodeVisitor { private static final String DelimOpen = "" ; private static final String DelimClose = "" ; final static boolean closeOnSameLine = true ; private IndentedWriter out ; private boolean withAnnotations = true ; private static final int annotationColumn = 40 ; public SqlNodeTextVisitor(IndentedWriter out) { this.out = out ; } public SqlNodeTextVisitor(IndentedWriter out, boolean withAnnotations) { this.out = out ; this.withAnnotations = withAnnotations ; } public void visit(SqlProject sqlNode) { start(sqlNode, "Project", sqlNode.getAliasName()) ; if ( sqlNode.getCols().size() == 0 ) out.println("<no cols>") ; else print(sqlNode.getCols()) ; sqlNode.getSubNode().visit(this) ; finish() ; } private void print(List<ColAlias> cols) { boolean first = true ; String currentPrefix = null ; for ( ColAlias c : cols ) { if ( ! first ) out.print(" ") ; first = false ; // Choose split points. String cn = c.getColumn().getFullColumnName() ; int j = cn.lastIndexOf(".") ; if ( j == -1 ) currentPrefix = null ; else { String x = cn.substring(0, j) ; if ( currentPrefix != null && ! x.equals(currentPrefix) ) out.println() ; currentPrefix = x ; } // Print out.print(c.getColumn().getFullColumnName()) ; if ( c.getAlias() != null ) { out.print("/") ; out.print(c.getAlias().getColumnName()) ; } } out.ensureStartOfLine() ; } public void visit(SqlDistinct sqlNode) { start(sqlNode, "Distinct", sqlNode.getAliasName()) ; sqlNode.getSubNode().visit(this) ; finish() ; } public void visit(SqlRestrict sqlNode) { start(sqlNode, "Restrict", null) ; print(sqlNode.getConditions()); sqlNode.getSubNode().visit(this) ; finish() ; } private void print(SqlExprList exprs) { for ( SqlExpr c : exprs ) out.println(c.toString()) ; } public void visit(SqlRename sqlRename) { start(sqlRename, "Rename", sqlRename.getAliasName()) ; out.incIndent() ; if ( ! sqlRename.getIdScope().isEmpty() ) out.println(sqlRename.getIdScope().toString()) ; if ( ! sqlRename.getNodeScope().isEmpty() ) out.println(sqlRename.getNodeScope().toString()) ; out.decIndent() ; sqlRename.getSubNode().visit(this) ; finish() ; } @Override public void visit(SqlTable sqlNode) { // if ( ! sqlNode.hasOneNote() ) // addAnnotations(sqlNode) ; out.print(DelimOpen) ; out.print("Table ") ; out.print(sqlNode.getAliasName()) ; out.print(DelimClose) ; // if ( sqlNode.hasOneNote() ) addAnnotations(sqlNode) ; } @Override public void visit(SqlJoinInner sqlJoin) { visitJoin(sqlJoin) ; } @Override public void visit(SqlJoinLeftOuter sqlJoin) { visitJoin(sqlJoin) ; } @Override public void visit(SqlUnion sqlUnion) { out.ensureStartOfLine() ; start(sqlUnion, "Union", sqlUnion.getAliasName()) ; if ( sqlUnion.getLeft() == null ) out.println("<null>") ; else sqlUnion.getLeft().visit(this) ; out.println() ; if ( sqlUnion.getRight() == null ) out.println("<null>") ; else sqlUnion.getRight().visit(this) ; finish() ; } @Override public void visit(SqlCoalesce sqlNode) { start(sqlNode, "Coalesce", sqlNode.getAliasName()) ; boolean first = true ; SqlJoin join = sqlNode.getJoinNode() ; for ( Var v : sqlNode.getCoalesceVars() ) { if ( ! first ) out.print(" ") ; first = false ; SqlColumn col = sqlNode.getIdScope().findScopeForVar(v).getColumn() ; out.print(v.toString()) ; SqlColumn leftCol = join.getLeft().getIdScope().findScopeForVar(v).getColumn() ; SqlColumn rightCol = join.getRight().getIdScope().findScopeForVar(v).getColumn() ; out.print("["+leftCol+"/"+rightCol+"]") ; } for ( Var v : sqlNode.getNonCoalesceVars() ) { if ( ! first ) out.print(" ") ; first = false ; out.print(v.toString()) ; // and where is came from. SqlColumn col = join.getIdScope().findScopeForVar(v).getColumn() ; out.print("["+col+"]") ; } out.ensureStartOfLine() ; visitJoin(sqlNode.getJoinNode()) ; finish() ; } public void visit(SqlSlice sqlNode) { String startStr = "--" ; String lengthStr = "--" ; if ( sqlNode.getStart() >= 0 ) startStr = Long.toString(sqlNode.getStart()) ; if ( sqlNode.getLength() >= 0 ) lengthStr = Long.toString(sqlNode.getLength()) ; String str = String.format("(%s, %s)", startStr, lengthStr) ; start(sqlNode, "Slice "+str, null) ; out.incIndent() ; sqlNode.getSubNode().visit(this) ; out.decIndent() ; finish() ; } @Override public void visit(SqlSelectBlock sqlNode) { start(sqlNode, "SqlSelectBlock", sqlNode.getAliasName()) ; if ( sqlNode.getDistinct() ) out.println("Distinct") ; out.incIndent() ; print(sqlNode.getCols()) ; print(sqlNode.getConditions()) ; out.decIndent() ; if ( sqlNode.getStart() >= 0 || sqlNode.getLength() >= 0 ) { String startStr = "--" ; String lengthStr = "--" ; if ( sqlNode.getStart() >= 0 ) startStr = Long.toString(sqlNode.getStart()) ; if ( sqlNode.getLength() >= 0 ) lengthStr = Long.toString(sqlNode.getLength()) ; String str = String.format("Slice: (%s, %s)", startStr, lengthStr) ; out.print(str) ; } sqlNode.getSubNode().visit(this) ; finish() ; } int depth = 0 ; private void visitJoin(SqlJoin sqlJoin) { depth ++ ; out.ensureStartOfLine() ; start(sqlJoin, sqlJoin.getJoinType().printName(), sqlJoin.getAliasName()) ; if ( sqlJoin.getLeft() == null ) out.println("<null>") ; else sqlJoin.getLeft().visit(this) ; out.println() ; if ( sqlJoin.getRight() == null ) out.println("<null>") ; else sqlJoin.getRight().visit(this) ; outputConditionList(sqlJoin.getConditions()) ; finish() ; depth -- ; } private void addAnnotations(Annotations n) { if ( ! withAnnotations ) return ; if ( n == null || !n.hasNotes() ) return ; boolean first = true ; // if ( n.getNotes().size() == 1 ) // { // out.pad(annotationColumn) ; // out.print(" -- ") ; // out.print(n.getNotes().get(0)) ; // return ; // } for ( String s : n.getNotes() ) { if ( !first ) out.ensureStartOfLine() ; first = false ; out.pad(annotationColumn, true ) ; out.print(" -- ") ; out.print(s) ; } } private void outputConditionList(Collection<SqlExpr>cond) { boolean first = true ; for ( SqlExpr c : cond ) { out.println() ; first = false ; out.print(DelimOpen) ; out.print("Condition ") ; out.print(c.toString()) ; addAnnotations(c) ; out.print(DelimClose) ; } } private void start(SqlNode sqlNode, String label, String alias) { out.print(DelimOpen) ; out.print(label) ; if ( alias != null ) { out.print("/") ; out.print(alias) ; } addAnnotations(sqlNode) ; out.incIndent() ; out.println() ; } private void finish() { if ( ! closeOnSameLine ) out.println() ; out.print(DelimClose) ; out.decIndent() ; } }