Skip to content

Commit

Permalink
TEIID-5740 adding support for explain
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Oct 31, 2019
1 parent 3a9139e commit c6120c7
Show file tree
Hide file tree
Showing 15 changed files with 274 additions and 54 deletions.
7 changes: 7 additions & 0 deletions api/src/main/java/org/teiid/language/SQLConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ public interface NonReserved {
static final String LISTAGG = "LISTAGG"; //$NON-NLS-1$

static final String OBJECT = "OBJECT"; //$NON-NLS-1$

//explain
static final String EXPLAIN = "EXPLAIN"; //$NON-NLS-1$
static final String FORMAT = "FORMAT"; //$NON-NLS-1$
static final String YAML = "YAML"; //$NON-NLS-1$
static final String ANALYZE = "ANALYZE"; //$NON-NLS-1$
static final String TEXT = "TEXT"; //$NON-NLS-1$
}

public interface Reserved {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ protected void generatePlan(boolean addLimit) throws TeiidComponentException, Te
prepPlan.setCommand(this.userCommand);

//there's no need to cache the plan if it's a stored procedure, since we already do that in the optimizer
boolean cache = !(this.userCommand instanceof StoredProcedure);
boolean cache = !(this.userCommand instanceof StoredProcedure && explainCommand == null);

// Defect 13751: Clone the plan in its current state (i.e. before processing) so that it can be used for later queries
prepPlan.setPlan(cache?processPlan.clone():processPlan, this.context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ public static ProcessorPlan optimizePlan(Command command, QueryMetadataInterface
analysisRecord.println("OPTIMIZE: \n" + command); //$NON-NLS-1$
}

command = command.getActualCommand();

if (command instanceof Insert) {
Insert insert = (Insert)command;
if (insert.isUpsert()) {
Expand Down
20 changes: 1 addition & 19 deletions engine/src/main/java/org/teiid/query/parser/QueryParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.util.CommandContext;

/**
* <p>Converts a SQL-string to an object version of a query. This
Expand Down Expand Up @@ -167,30 +166,13 @@ public Command parseProcedure(String sql, boolean update) throws QueryParserExce
* @throws IllegalArgumentException if sql is null
*/
public Command parseCommand(String sql, ParseInfo parseInfo) throws QueryParserException {
return parseCommand(sql, parseInfo, false);
}

public Command parseDesignerCommand(String sql) throws QueryParserException {
return parseCommand(sql, new ParseInfo(), true);
}

public Command parseCommand(String sql, ParseInfo parseInfo, boolean designerCommands) throws QueryParserException {
return parseCommand(sql, parseInfo, designerCommands, null, null, null, null);
}

public Command parseCommand(final String sql, ParseInfo parseInfo, boolean designerCommands, String vdbName,
String vdbVersion, String schemaName, CommandContext commandContext) throws QueryParserException {
if(sql == null || sql.length() == 0) {
throw new QueryParserException(QueryPlugin.Event.TEIID30377, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30377));
}

Command result = null;
try{
if (designerCommands) {
result = getSqlParser(sql).designerCommand(parseInfo);
} else {
result = getSqlParser(sql).command(parseInfo);
}
result = getSqlParser(sql).command(parseInfo);
result.setCacheHint(SQLParserUtil.getQueryCacheOption(sql));
} catch(ParseException pe) {
if(sql.startsWith(XML_OPEN_BRACKET) || sql.startsWith(XQUERY_DECLARE)) {
Expand Down
14 changes: 14 additions & 0 deletions engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.ExplainCommand;
import org.teiid.query.sql.lang.GroupContext;
import org.teiid.query.sql.lang.ProcedureContainer;
import org.teiid.query.sql.lang.Query;
Expand Down Expand Up @@ -91,6 +92,17 @@ public void resolveCommand(Command command, TempMetadataAdapter metadata,
QueryResolverException, TeiidComponentException {
}
};
private static final CommandResolver EXPLAIN_RESOLVER = new CommandResolver() {

@Override
public void resolveCommand(Command command, TempMetadataAdapter metadata,
boolean resolveNullLiterals) throws QueryMetadataException,
QueryResolverException, TeiidComponentException {
Command actual = ((ExplainCommand)command).getCommand();
CommandResolver resolver = chooseResolver(actual, metadata);
resolver.resolveCommand(actual, metadata, resolveNullLiterals);
}
};

public static Command expandCommand(ProcedureContainer proc, QueryMetadataInterface metadata, AnalysisRecord analysisRecord) throws QueryResolverException, QueryMetadataException, TeiidComponentException {
ProcedureContainerResolver cr = (ProcedureContainerResolver)chooseResolver(proc, metadata);
Expand Down Expand Up @@ -192,6 +204,8 @@ public static TempMetadataStore resolveCommand(Command currentCommand, QueryMeta
private static CommandResolver chooseResolver(Command command, QueryMetadataInterface metadata) {

switch(command.getType()) {
case Command.TYPE_EXPLAIN:
return EXPLAIN_RESOLVER;
case Command.TYPE_QUERY:
if(command instanceof Query) {
return SIMPLE_QUERY_RESOLVER;
Expand Down
2 changes: 2 additions & 0 deletions engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,6 @@ public void visit(XMLCast xmlCast) {}
public void visit(IsDistinctCriteria isDistinctCriteria) {}

public void visit(JsonTable jsonTable) {}

public void visit(ExplainCommand explainCommand) {}
}
12 changes: 11 additions & 1 deletion engine/src/main/java/org/teiid/query/sql/lang/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public abstract class Command implements LanguageObject {

public static final int TYPE_ALTER_TRIGGER = 16;

public static final int TYPE_EXPLAIN = 17;

public static final int TYPE_SOURCE_EVENT = -1;

private static List<Expression> updateCommandSymbol;
Expand Down Expand Up @@ -158,7 +160,7 @@ public void setExternalGroupContexts(GroupContext root) {
if (root == null) {
this.externalGroups = null;
} else {
this.externalGroups = (GroupContext)root.clone();
this.externalGroups = root.clone();
}
}

Expand Down Expand Up @@ -359,4 +361,12 @@ public static String getCommandToken(int commandType) {
return "?"; //$NON-NLS-1$
}

/**
* For a statement such as explain, obtain the actual command
* @return
*/
public Command getActualCommand() {
return this;
}

}
130 changes: 130 additions & 0 deletions engine/src/main/java/org/teiid/query/sql/lang/ExplainCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags and
* the COPYRIGHT.txt file distributed with this work.
*
* Licensed 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.teiid.query.sql.lang;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.teiid.core.types.DataTypeManager.DefaultDataClasses;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;

public class ExplainCommand extends Command {

public enum Format {
TEXT,
XML,
YAML
}

private Format format;
private Boolean analyze;
private Command command;

@Override
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
}

@Override
public int getType() {
return Command.TYPE_EXPLAIN;
}

@Override
public ExplainCommand clone() {
ExplainCommand clone = new ExplainCommand();
clone.setFormat(format);
clone.setAnalyze(analyze);
if (command != null) {
clone.setCommand((Command) command.clone());
}
return clone;
}

@Override
public List<Expression> getProjectedSymbols() {
Class<?> type = DefaultDataClasses.CLOB;
if (format == Format.XML) {
type = DefaultDataClasses.XML;
}
ElementSymbol symbol = new ElementSymbol("QUERY PLAN"); //$NON-NLS-1$
symbol.setType(type);
return Arrays.asList(symbol);
}

@Override
public boolean areResultsCachable() {
return false;
}

public Format getFormat() {
return format;
}

public void setFormat(Format format) {
this.format = format;
}

public Boolean getAnalyze() {
return analyze;
}

public void setAnalyze(Boolean analyze) {
this.analyze = analyze;
}

public Command getCommand() {
return command;
}

public void setCommand(Command command) {
this.command = command;
}

@Override
public int hashCode() {
return Objects.hash(analyze, command, format);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ExplainCommand other = (ExplainCommand) obj;
return Objects.equals(analyze, other.analyze)
&& Objects.equals(command, other.command)
&& Objects.equals(format, other.format);
}

@Override
public Command getActualCommand() {
return command;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,13 @@ public void visit(IsDistinctCriteria obj) {
postVisitVisitor(obj);
}

@Override
public void visit(ExplainCommand explainCommand) {
preVisitVisitor(explainCommand);
visitNode(explainCommand.getCommand());
postVisitVisitor(explainCommand);
}

public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
doVisit(object, visitor, order, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2732,4 +2732,26 @@ static boolean isReservedWord( String string ) {
return SQLConstants.isReservedWord(string);
}

@Override
public void visit(ExplainCommand explainCommand) {
parts.append(NonReserved.EXPLAIN).append(SPACE);
if (explainCommand.getAnalyze() != null || explainCommand.getFormat() != null) {
parts.append(Tokens.LPAREN);
boolean needsComma = false;
if (explainCommand.getAnalyze() != null) {
parts.append(NonReserved.ANALYZE).append(SPACE).append(explainCommand.getAnalyze().toString());
needsComma = true;
}
if (explainCommand.getFormat() != null) {
if (needsComma) {
parts.append(Tokens.COMMA).append(SPACE);
}
parts.append(NonReserved.FORMAT).append(SPACE).append(explainCommand.getFormat().name());
needsComma = true;
}
parts.append(Tokens.RPAREN).append(SPACE);
}
visitNode(explainCommand.getCommand());
}

}
Loading

0 comments on commit c6120c7

Please sign in to comment.