@Override protected List<QuerySource> visitQueryBody(QueryBody node, QueryState state){ ArrayList<QuerySource> relations = new ArrayList<QuerySource>(); if(node instanceof Table){ String table = ((Table)node).getName().toString(); // resolve relations provided in dot notation (schema.index.type) and just get the type for now String[] catIndexType = table.split("\\."); if(catIndexType.length == 1) { relations.add(new QuerySource(table)); }else{ relations.add(new QuerySource(catIndexType[catIndexType.length-1])); } }else if (node instanceof TableSubquery){ TableSubquery ts = (TableSubquery)node; Object alias = state.getValue("table_alias"); Pattern queryRegex = Pattern.compile("from\\s*\\((.+)\\)\\s*(where|as|having|limit|$"+(alias==null ? "":"|"+alias)+")", Pattern.CASE_INSENSITIVE); Matcher m = queryRegex.matcher(state.originalSql()); if(m.find()) { relations.add(new QuerySource(m.group(1), ts.getQuery().getQueryBody())); }else state.addException("Unable to parse provided subquery in FROM clause"); }else state.addException("Unable to parse FROM clause, "+node.getClass().getName()+" is not supported"); return relations; }
@Override protected Void visitTableSubquery(TableSubquery node, Integer indent) { if (_createTempTable == true) { process(node.getQuery(), indent); } else { super.visitTableSubquery(node, indent); } return null; }
@Override protected Void visitTableSubquery(TableSubquery node, Integer indent) { // 20141121: remove "()" around select //builder.append('(').append('\n'); builder.append('\n'); process(node.getQuery(), indent + 1); // 20141121: remove "()" around select //append(indent, ") "); append(indent, " "); return null; }
@Override protected Void visitQuery(Query node, Integer indent) { if (node.getWith().isPresent()) { With with = node.getWith().get(); append(indent, "WITH"); if (with.isRecursive()) { builder.append(" RECURSIVE"); } builder.append("\n "); Iterator<WithQuery> queries = with.getQueries().iterator(); while (queries.hasNext()) { WithQuery query = queries.next(); append(indent, query.getName()); query.getColumnNames().ifPresent(columnNames -> appendAliasColumns(builder, columnNames)); builder.append(" AS "); process(new TableSubquery(query.getQuery()), indent); builder.append('\n'); if (queries.hasNext()) { builder.append(", "); } } } processRelation(node.getQueryBody(), indent); if (node.getOrderBy().isPresent()) { append(indent, "ORDER BY " + formatSortItems(node.getOrderBy().get().getSortItems(), parameters, indent)) .append('\n'); } if (node.getLimit().isPresent()) { append(indent, "LIMIT " + node.getLimit().get()) .append('\n'); } return null; }
@Override protected Void visitTableSubquery(TableSubquery node, Integer indent) { builder.append('(') .append('\n'); process(node.getQuery(), indent + 1); append(indent, ") "); return null; }
@Override protected RelationType visitTableSubquery(TableSubquery node, AnalysisContext context) { StatementAnalyzer analyzer = new StatementAnalyzer(analysis, metadata, sqlParser, accessControl, session, experimentalSyntaxEnabled, Optional.empty()); RelationType descriptor = analyzer.process(node.getQuery(), context); analysis.setOutputDescriptor(node, descriptor); return descriptor; }
@Override protected RelationPlan visitTableSubquery(TableSubquery node, Void context) { return process(node.getQuery(), context); }
@Override protected Void visitQuery(Query node, Integer indent) { if (node.getWith().isPresent()) { With with = node.getWith().get(); append(indent, "WITH"); if (with.isRecursive()) { builder.append(" RECURSIVE"); } builder.append("\n "); Iterator<WithQuery> queries = with.getQueries().iterator(); while (queries.hasNext()) { WithQuery query = queries.next(); append(indent, query.getName()); appendAliasColumns(builder, query.getColumnNames()); builder.append(" AS "); process(new TableSubquery(query.getQuery()), indent); builder.append('\n'); if (queries.hasNext()) { builder.append(", "); } } } processRelation(node.getQueryBody(), indent); if (!node.getOrderBy().isEmpty()) { append(indent, "ORDER BY " + formatSortItems(node.getOrderBy())) .append('\n'); } if (node.getLimit().isPresent()) { append(indent, "LIMIT " + node.getLimit().get()) .append('\n'); } if (node.getApproximate().isPresent()) { String confidence = node.getApproximate().get().getConfidence(); append(indent, "APPROXIMATE AT " + confidence + " CONFIDENCE") .append('\n'); } return null; }
@Override public Node visitSubquery(SqlBaseParser.SubqueryContext context) { return new TableSubquery(getLocation(context), (Query) visit(context.queryNoWith())); }
@Override public Node visitSubqueryRelation(SqlBaseParser.SubqueryRelationContext context) { return new TableSubquery(getLocation(context), (Query) visit(context.query())); }
public static Relation subquery(Query query) { return new TableSubquery(query); }