Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.trino.sql.rewrite.DescribeInputRewrite Maven / Gradle / Ivy
/*
* 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 io.trino.sql.rewrite;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import io.trino.Session;
import io.trino.execution.querystats.PlanOptimizersStatsCollector;
import io.trino.execution.warnings.WarningCollector;
import io.trino.spi.type.Type;
import io.trino.sql.analyzer.Analysis;
import io.trino.sql.analyzer.Analyzer;
import io.trino.sql.analyzer.AnalyzerFactory;
import io.trino.sql.parser.SqlParser;
import io.trino.sql.tree.AstVisitor;
import io.trino.sql.tree.Cast;
import io.trino.sql.tree.DescribeInput;
import io.trino.sql.tree.Expression;
import io.trino.sql.tree.Limit;
import io.trino.sql.tree.LongLiteral;
import io.trino.sql.tree.Node;
import io.trino.sql.tree.NodeRef;
import io.trino.sql.tree.NullLiteral;
import io.trino.sql.tree.Parameter;
import io.trino.sql.tree.Query;
import io.trino.sql.tree.Row;
import io.trino.sql.tree.Statement;
import io.trino.sql.tree.StringLiteral;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static io.trino.SystemSessionProperties.isOmitDateTimeTypePrecision;
import static io.trino.execution.ParameterExtractor.extractParameters;
import static io.trino.spi.type.BigintType.BIGINT;
import static io.trino.spi.type.VarcharType.VARCHAR;
import static io.trino.sql.QueryUtil.aliased;
import static io.trino.sql.QueryUtil.ascending;
import static io.trino.sql.QueryUtil.identifier;
import static io.trino.sql.QueryUtil.ordering;
import static io.trino.sql.QueryUtil.row;
import static io.trino.sql.QueryUtil.selectList;
import static io.trino.sql.QueryUtil.simpleQuery;
import static io.trino.sql.QueryUtil.values;
import static io.trino.sql.analyzer.QueryType.DESCRIBE;
import static io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType;
import static io.trino.type.TypeUtils.getDisplayLabel;
import static io.trino.type.UnknownType.UNKNOWN;
import static java.util.Objects.requireNonNull;
public final class DescribeInputRewrite
implements StatementRewrite.Rewrite
{
private final SqlParser parser;
@Inject
public DescribeInputRewrite(SqlParser parser)
{
this.parser = requireNonNull(parser, "parser is null");
}
@Override
public Statement rewrite(
AnalyzerFactory analyzerFactory,
Session session,
Statement node,
List parameters,
Map, Expression> parameterLookup,
WarningCollector warningCollector,
PlanOptimizersStatsCollector planOptimizersStatsCollector)
{
return (Statement) new Visitor(session, parser, analyzerFactory, parameters, parameterLookup, warningCollector, planOptimizersStatsCollector).process(node, null);
}
private static final class Visitor
extends AstVisitor
{
private static final Query EMPTY_INPUT = createDesctibeInputQuery(
new Row[] {row(
new Cast(new NullLiteral(), toSqlType(BIGINT)),
new Cast(new NullLiteral(), toSqlType(VARCHAR)))},
Optional.of(new Limit(new LongLiteral("0"))));
private final Session session;
private final SqlParser parser;
private final AnalyzerFactory analyzerFactory;
private final List parameters;
private final Map, Expression> parameterLookup;
private final WarningCollector warningCollector;
private final PlanOptimizersStatsCollector planOptimizersStatsCollector;
public Visitor(
Session session,
SqlParser parser,
AnalyzerFactory analyzerFactory,
List parameters,
Map, Expression> parameterLookup,
WarningCollector warningCollector,
PlanOptimizersStatsCollector planOptimizersStatsCollector)
{
this.session = requireNonNull(session, "session is null");
this.parser = requireNonNull(parser, "parser is null");
this.analyzerFactory = requireNonNull(analyzerFactory, "analyzerFactory is null");
this.parameters = parameters;
this.parameterLookup = parameterLookup;
this.warningCollector = requireNonNull(warningCollector, "warningCollector is null");
this.planOptimizersStatsCollector = requireNonNull(planOptimizersStatsCollector, "planOptimizersStatsCollector is null");
}
@Override
protected Node visitDescribeInput(DescribeInput node, Void context)
{
String sqlString = session.getPreparedStatement(node.getName().getValue());
Statement statement = parser.createStatement(sqlString);
// create analysis for the query we are describing.
Analyzer analyzer = analyzerFactory.createAnalyzer(session, parameters, parameterLookup, warningCollector, planOptimizersStatsCollector);
Analysis analysis = analyzer.analyze(statement, DESCRIBE);
// get all parameters in query
List parameters = extractParameters(statement);
ImmutableList.Builder builder = ImmutableList.builder();
for (int i = 0; i < parameters.size(); i++) {
builder.add(createDescribeInputRow(session, i, parameters.get(i), analysis));
}
// return the positions and types of all parameters
Row[] rows = builder.build().toArray(Row[]::new);
Optional limit = Optional.empty();
if (rows.length == 0) {
return EMPTY_INPUT;
}
return createDesctibeInputQuery(rows, limit);
}
private static Query createDesctibeInputQuery(Row[] rows, Optional limit)
{
return simpleQuery(
selectList(identifier("Position"), identifier("Type")),
aliased(
values(rows),
"Parameter Input",
ImmutableList.of("Position", "Type")),
Optional.empty(),
Optional.empty(),
Optional.empty(),
Optional.of(ordering(ascending("Position"))),
Optional.empty(),
limit);
}
private static Row createDescribeInputRow(Session session, int position, Parameter parameter, Analysis queryAnalysis)
{
Type type = queryAnalysis.getCoercion(parameter);
if (type == null) {
type = UNKNOWN;
}
return row(
new LongLiteral(Integer.toString(position)),
new StringLiteral(getDisplayLabel(type, isOmitDateTimeTypePrecision(session))));
}
@Override
protected Node visitNode(Node node, Void context)
{
return node;
}
}
}