org.apache.phoenix.pig.util.QuerySchemaParserFunction Maven / Gradle / Ivy
/*
* 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 maynot 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 applicablelaw 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.phoenix.pig.util;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.compile.ColumnProjector;
import org.apache.phoenix.compile.QueryPlan;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.mapreduce.util.ConnectionUtil;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
/**
*
* A function to parse the select query passed to LOAD into a Pair of
*
*/
public class QuerySchemaParserFunction implements Function> {
private static final Log LOG = LogFactory.getLog(QuerySchemaParserFunction.class);
private final Configuration configuration;
public QuerySchemaParserFunction(Configuration configuration) {
Preconditions.checkNotNull(configuration);
this.configuration = configuration;
}
@Override
public Pair apply(final String selectStatement) {
Preconditions.checkNotNull(selectStatement);
Preconditions.checkArgument(!selectStatement.isEmpty(), "Select Query is empty!!");
Connection connection = null;
try {
connection = ConnectionUtil.getInputConnection(this.configuration);
final Statement statement = connection.createStatement();
final PhoenixStatement pstmt = statement.unwrap(PhoenixStatement.class);
final QueryPlan queryPlan = pstmt.compileQuery(selectStatement);
isValidStatement(queryPlan);
final String tableName = queryPlan.getTableRef().getTable().getName().getString();
final List extends ColumnProjector> projectedColumns = queryPlan.getProjector().getColumnProjectors();
final List columns = Lists.transform(projectedColumns,
new Function() {
@Override
public String apply(ColumnProjector column) {
return column.getName();
}
});
final String columnsAsStr = Joiner.on(",").join(columns);
return new Pair(tableName, columnsAsStr);
} catch (SQLException e) {
LOG.error(String.format(" Error [%s] parsing SELECT query [%s] ",e.getMessage(),selectStatement));
throw new RuntimeException(e);
} finally {
if(connection != null) {
try {
connection.close();
} catch(SQLException sqle) {
LOG.error(" Error closing connection ");
throw new RuntimeException(sqle);
}
}
}
}
/**
* The method validates the statement passed to the query plan. List of conditions are
*
* - Is a SELECT statement
* - doesn't contain ORDER BY expression
* - doesn't contain LIMIT
* - doesn't contain GROUP BY expression
* - doesn't contain DISTINCT
* - doesn't contain AGGREGATE functions
*
* @param queryPlan
* @return
*/
private boolean isValidStatement(final QueryPlan queryPlan) {
if(queryPlan.getStatement().getOperation() != PhoenixStatement.Operation.QUERY) {
throw new IllegalArgumentException("Query passed isn't a SELECT statement");
}
if(!queryPlan.getOrderBy().getOrderByExpressions().isEmpty()
|| queryPlan.getLimit() != null
|| (queryPlan.getGroupBy() != null && !queryPlan.getGroupBy().isEmpty())
|| queryPlan.getStatement().isDistinct()
|| queryPlan.getStatement().isAggregate()) {
throw new IllegalArgumentException("SELECT statement shouldn't contain DISTINCT or ORDER BY or LIMIT or GROUP BY expressions");
}
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy