@Override protected Void visitExplain(Explain node, Integer indent) { builder.append("EXPLAIN "); if (node.isAnalyze()) { builder.append("ANALYZE "); } List<String> options = new ArrayList<>(); for (ExplainOption option : node.getOptions()) { if (option instanceof ExplainType) { options.add("TYPE " + ((ExplainType) option).getType()); } else if (option instanceof ExplainFormat) { options.add("FORMAT " + ((ExplainFormat) option).getType()); } else { throw new UnsupportedOperationException("unhandled explain option: " + option); } } if (!options.isEmpty()) { builder.append("("); Joiner.on(", ").appendTo(builder, options); builder.append(")"); } builder.append("\n"); process(node.getStatement(), indent); return null; }
@Override public Node visitExplainFormat(SqlBaseParser.ExplainFormatContext context) { switch (context.value.getType()) { case SqlBaseLexer.GRAPHVIZ: return new ExplainFormat(getLocation(context), ExplainFormat.Type.GRAPHVIZ); case SqlBaseLexer.TEXT: return new ExplainFormat(getLocation(context), ExplainFormat.Type.TEXT); case SqlBaseLexer.JSON: return new ExplainFormat(getLocation(context), ExplainFormat.Type.JSON); } throw new IllegalArgumentException("Unsupported EXPLAIN format: " + context.value.getText()); }
@Override protected Node visitExplain(Explain node, Void context) throws SemanticException { if (node.isAnalyze()) { Statement statement = (Statement) process(node.getStatement(), context); return new Explain(statement, node.isAnalyze(), node.isVerbose(), node.getOptions()); } ExplainType.Type planType = LOGICAL; ExplainFormat.Type planFormat = TEXT; List<ExplainOption> options = node.getOptions(); for (ExplainOption option : options) { if (option instanceof ExplainType) { planType = ((ExplainType) option).getType(); // Use JSON as the default format for EXPLAIN (TYPE IO). if (planType == IO) { planFormat = JSON; } break; } } for (ExplainOption option : options) { if (option instanceof ExplainFormat) { planFormat = ((ExplainFormat) option).getType(); break; } } return getQueryPlan(node, planType, planFormat); }
@Test public void testExplain() { assertStatement("EXPLAIN SELECT * FROM t", new Explain(simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, false, ImmutableList.of())); assertStatement("EXPLAIN (TYPE LOGICAL) SELECT * FROM t", new Explain( simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, false, ImmutableList.of(new ExplainType(ExplainType.Type.LOGICAL)))); assertStatement("EXPLAIN (TYPE LOGICAL, FORMAT TEXT) SELECT * FROM t", new Explain( simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, false, ImmutableList.of( new ExplainType(ExplainType.Type.LOGICAL), new ExplainFormat(ExplainFormat.Type.TEXT)))); }
@Override protected Void visitExplain(Explain node, Integer indent) { builder.append("EXPLAIN "); if (node.isAnalyze()) { builder.append("ANALYZE "); } List<String> options = new ArrayList<>(); for (ExplainOption option : node.getOptions()) { if (option instanceof ExplainType) { options.add("TYPE " + ((ExplainType) option).getType()); } else if (option instanceof ExplainFormat) { options.add("FORMAT " + ((ExplainFormat) option).getType()); } else { throw new UnsupportedOperationException("unhandled explain option: " + option); } } if (!options.isEmpty()) { builder.append("("); Joiner.on(", ").appendTo(builder, options); builder.append(")"); } builder.append("\n"); process(node.getStatement(), indent); return null; }
@Override public Node visitExplainFormat(SqlBaseParser.ExplainFormatContext context) { switch (context.value.getType()) { case SqlBaseLexer.GRAPHVIZ: return new ExplainFormat(getLocation(context), ExplainFormat.Type.GRAPHVIZ); case SqlBaseLexer.TEXT: return new ExplainFormat(getLocation(context), ExplainFormat.Type.TEXT); case SqlBaseLexer.JSON: return new ExplainFormat(getLocation(context), ExplainFormat.Type.JSON); } throw new IllegalArgumentException("Unsupported EXPLAIN format: " + context.value.getText()); }
@Override protected Void visitExplain(Explain node, Integer indent) { builder.append("EXPLAIN "); List<String> options = new ArrayList<>(); for (ExplainOption option : node.getOptions()) { if (option instanceof ExplainType) { options.add("TYPE " + ((ExplainType) option).getType()); } else if (option instanceof ExplainFormat) { options.add("FORMAT " + ((ExplainFormat) option).getType()); } else { throw new UnsupportedOperationException("unhandled explain option: " + option); } } if (!options.isEmpty()) { builder.append("("); Joiner.on(", ").appendTo(builder, options); builder.append(")"); } builder.append("\n"); process(node.getStatement(), indent); return null; }
@Override public Node visitExplainFormat(SqlBaseParser.ExplainFormatContext context) { switch (context.value.getType()) { case SqlBaseLexer.GRAPHVIZ: return new ExplainFormat(getLocation(context), ExplainFormat.Type.GRAPHVIZ); case SqlBaseLexer.TEXT: return new ExplainFormat(getLocation(context), ExplainFormat.Type.TEXT); } throw new IllegalArgumentException("Unsupported EXPLAIN format: " + context.value.getText()); }
@Override protected Void visitExplain(Explain node, Integer indent) { builder.append("EXPLAIN "); if (node.isAnalyze()) { builder.append("ANALYZE "); } List<String> options = new ArrayList<>(); for (ExplainOption option : node.getOptions()) { if (option instanceof ExplainType) { options.add("TYPE " + ((ExplainType) option).getType()); } else if (option instanceof ExplainFormat) { options.add("FORMAT " + ((ExplainFormat) option).getType()); } else { throw new UnsupportedOperationException("unhandled explain option: " + option); } } if (!options.isEmpty()) { builder.append("("); Joiner.on(", ").appendTo(builder, options); builder.append(")"); } builder.append("\n"); process(node.getStatement(), indent); return null; }
@Test public void testExplain() { assertStatement("EXPLAIN SELECT * FROM t", new Explain(simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, false, ImmutableList.of())); assertStatement("EXPLAIN (TYPE LOGICAL) SELECT * FROM t", new Explain( simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, false, ImmutableList.of(new ExplainType(ExplainType.Type.LOGICAL)))); assertStatement("EXPLAIN (TYPE LOGICAL, FORMAT TEXT) SELECT * FROM t", new Explain( simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, false, ImmutableList.of( new ExplainType(ExplainType.Type.LOGICAL), new ExplainFormat(ExplainFormat.Type.TEXT)))); }
@Override protected Void visitExplain(Explain node, Integer indent) { builder.append("EXPLAIN "); if (node.isAnalyze()) { builder.append("ANALYZE "); } List<String> options = new ArrayList<>(); for (ExplainOption option : node.getOptions()) { if (option instanceof ExplainType) { options.add("TYPE " + ((ExplainType) option).getType()); } else if (option instanceof ExplainFormat) { options.add("FORMAT " + ((ExplainFormat) option).getType()); } else { throw new UnsupportedOperationException("unhandled explain option: " + option); } } if (!options.isEmpty()) { builder.append("("); Joiner.on(", ").appendTo(builder, options); builder.append(")"); } builder.append("\n"); process(node.getStatement(), indent); return null; }
@Test public void testExplain() throws Exception { assertStatement("EXPLAIN SELECT * FROM t", new Explain(simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, ImmutableList.of())); assertStatement("EXPLAIN (TYPE LOGICAL) SELECT * FROM t", new Explain( simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, ImmutableList.of(new ExplainType(ExplainType.Type.LOGICAL)))); assertStatement("EXPLAIN (TYPE LOGICAL, FORMAT TEXT) SELECT * FROM t", new Explain( simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false, ImmutableList.of( new ExplainType(ExplainType.Type.LOGICAL), new ExplainFormat(ExplainFormat.Type.TEXT)))); }
planFormat = ((ExplainFormat) option).getType(); break;