use of org.apache.phoenix.schema.FunctionNotFoundException in project phoenix by apache.
the class PostDDLCompiler method compile.
public MutationPlan compile(final List<TableRef> tableRefs, final byte[] emptyCF, final List<byte[]> projectCFs, final List<PColumn> deleteList, final long timestamp) throws SQLException {
PhoenixStatement statement = new PhoenixStatement(connection);
final StatementContext context = new StatementContext(statement, new ColumnResolver() {
@Override
public List<TableRef> getTables() {
return tableRefs;
}
@Override
public TableRef resolveTable(String schemaName, String tableName) throws SQLException {
throw new UnsupportedOperationException();
}
@Override
public ColumnRef resolveColumn(String schemaName, String tableName, String colName) throws SQLException {
throw new UnsupportedOperationException();
}
@Override
public List<PFunction> getFunctions() {
return Collections.<PFunction>emptyList();
}
@Override
public PFunction resolveFunction(String functionName) throws SQLException {
throw new FunctionNotFoundException(functionName);
}
@Override
public boolean hasUDFs() {
return false;
}
@Override
public PSchema resolveSchema(String schemaName) throws SQLException {
throw new SchemaNotFoundException(schemaName);
}
@Override
public List<PSchema> getSchemas() {
throw new UnsupportedOperationException();
}
}, scan, new SequenceManager(statement));
return new BaseMutationPlan(context, Operation.UPSERT) {
/* FIXME */
@Override
public MutationState execute() throws SQLException {
if (tableRefs.isEmpty()) {
return new MutationState(0, 1000, connection);
}
boolean wasAutoCommit = connection.getAutoCommit();
try {
connection.setAutoCommit(true);
SQLException sqlE = null;
/*
* Handles:
* 1) deletion of all rows for a DROP TABLE and subsequently deletion of all rows for a DROP INDEX;
* 2) deletion of all column values for a ALTER TABLE DROP COLUMN
* 3) updating the necessary rows to have an empty KV
* 4) updating table stats
*/
long totalMutationCount = 0;
for (final TableRef tableRef : tableRefs) {
Scan scan = ScanUtil.newScan(context.getScan());
SelectStatement select = SelectStatement.COUNT_ONE;
// We need to use this tableRef
ColumnResolver resolver = new ColumnResolver() {
@Override
public List<TableRef> getTables() {
return Collections.singletonList(tableRef);
}
@Override
public java.util.List<PFunction> getFunctions() {
return Collections.emptyList();
}
;
@Override
public TableRef resolveTable(String schemaName, String tableName) throws SQLException {
throw new UnsupportedOperationException();
}
@Override
public ColumnRef resolveColumn(String schemaName, String tableName, String colName) throws SQLException {
PColumn column = tableName != null ? tableRef.getTable().getColumnFamily(tableName).getPColumnForColumnName(colName) : tableRef.getTable().getColumnForColumnName(colName);
return new ColumnRef(tableRef, column.getPosition());
}
@Override
public PFunction resolveFunction(String functionName) throws SQLException {
throw new UnsupportedOperationException();
}
;
@Override
public boolean hasUDFs() {
return false;
}
@Override
public List<PSchema> getSchemas() {
throw new UnsupportedOperationException();
}
@Override
public PSchema resolveSchema(String schemaName) throws SQLException {
throw new SchemaNotFoundException(schemaName);
}
};
PhoenixStatement statement = new PhoenixStatement(connection);
StatementContext context = new StatementContext(statement, resolver, scan, new SequenceManager(statement));
long ts = timestamp;
// in this case, so maybe this is ok.
if (ts != HConstants.LATEST_TIMESTAMP && tableRef.getTable().isTransactional()) {
ts = TransactionUtil.convertToNanoseconds(ts);
}
ScanUtil.setTimeRange(scan, scan.getTimeRange().getMin(), ts);
if (emptyCF != null) {
scan.setAttribute(BaseScannerRegionObserver.EMPTY_CF, emptyCF);
scan.setAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER, EncodedColumnsUtil.getEmptyKeyValueInfo(tableRef.getTable()).getFirst());
}
ServerCache cache = null;
try {
if (deleteList != null) {
if (deleteList.isEmpty()) {
scan.setAttribute(BaseScannerRegionObserver.DELETE_AGG, QueryConstants.TRUE);
// In the case of a row deletion, add index metadata so mutable secondary indexing works
/* TODO: we currently manually run a scan to delete the index data here
ImmutableBytesWritable ptr = context.getTempPtr();
tableRef.getTable().getIndexMaintainers(ptr);
if (ptr.getLength() > 0) {
IndexMetaDataCacheClient client = new IndexMetaDataCacheClient(connection, tableRef);
cache = client.addIndexMetadataCache(context.getScanRanges(), ptr);
byte[] uuidValue = cache.getId();
scan.setAttribute(PhoenixIndexCodec.INDEX_UUID, uuidValue);
}
*/
} else {
// In the case of the empty key value column family changing, do not send the index
// metadata, as we're currently managing this from the client. It's possible for the
// data empty column family to stay the same, while the index empty column family
// changes.
PColumn column = deleteList.get(0);
byte[] cq = column.getColumnQualifierBytes();
if (emptyCF == null) {
scan.addColumn(column.getFamilyName().getBytes(), cq);
}
scan.setAttribute(BaseScannerRegionObserver.DELETE_CF, column.getFamilyName().getBytes());
scan.setAttribute(BaseScannerRegionObserver.DELETE_CQ, cq);
}
}
List<byte[]> columnFamilies = Lists.newArrayListWithExpectedSize(tableRef.getTable().getColumnFamilies().size());
if (projectCFs == null) {
for (PColumnFamily family : tableRef.getTable().getColumnFamilies()) {
columnFamilies.add(family.getName().getBytes());
}
} else {
for (byte[] projectCF : projectCFs) {
columnFamilies.add(projectCF);
}
}
// Need to project all column families into the scan, since we haven't yet created our empty key value
RowProjector projector = ProjectionCompiler.compile(context, SelectStatement.COUNT_ONE, GroupBy.EMPTY_GROUP_BY);
context.getAggregationManager().compile(context, GroupBy.EMPTY_GROUP_BY);
// since at this point we haven't added the empty key value everywhere.
if (columnFamilies != null) {
scan.getFamilyMap().clear();
for (byte[] family : columnFamilies) {
scan.addFamily(family);
}
projector = new RowProjector(projector, false);
}
// any other Post DDL operations.
try {
// Since dropping a VIEW does not affect the underlying data, we do
// not need to pass through the view statement here.
// Push where clause into scan
WhereCompiler.compile(context, select);
} catch (ColumnFamilyNotFoundException e) {
continue;
} catch (ColumnNotFoundException e) {
continue;
} catch (AmbiguousColumnException e) {
continue;
}
QueryPlan plan = new AggregatePlan(context, select, tableRef, projector, null, null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
try {
ResultIterator iterator = plan.iterator();
try {
Tuple row = iterator.next();
ImmutableBytesWritable ptr = context.getTempPtr();
totalMutationCount += (Long) projector.getColumnProjector(0).getValue(row, PLong.INSTANCE, ptr);
} catch (SQLException e) {
sqlE = e;
} finally {
try {
iterator.close();
} catch (SQLException e) {
if (sqlE == null) {
sqlE = e;
} else {
sqlE.setNextException(e);
}
} finally {
if (sqlE != null) {
throw sqlE;
}
}
}
} catch (TableNotFoundException e) {
// Ignore and continue, as HBase throws when table hasn't been written to
// FIXME: Remove if this is fixed in 0.96
}
} finally {
if (cache != null) {
// Remove server cache if there is one
cache.close();
}
}
}
final long count = totalMutationCount;
return new MutationState(1, 1000, connection) {
@Override
public long getUpdateCount() {
return count;
}
};
} finally {
if (!wasAutoCommit)
connection.setAutoCommit(wasAutoCommit);
}
}
};
}
use of org.apache.phoenix.schema.FunctionNotFoundException in project phoenix by apache.
the class ConnectionQueryServicesImpl method addFunction.
@Override
public void addFunction(PFunction function) throws SQLException {
synchronized (latestMetaDataLock) {
try {
throwConnectionClosedIfNullMetaData();
// If existing table isn't older than new table, don't replace
// If a client opens a connection at an earlier timestamp, this can happen
PFunction existingFunction = latestMetaData.getFunction(new PTableKey(function.getTenantId(), function.getFunctionName()));
if (existingFunction.getTimeStamp() >= function.getTimeStamp()) {
return;
}
} catch (FunctionNotFoundException e) {
}
latestMetaData.addFunction(function);
latestMetaDataLock.notifyAll();
}
}
use of org.apache.phoenix.schema.FunctionNotFoundException in project phoenix by apache.
the class ConnectionlessQueryServicesImpl method getFunctions.
@Override
public MetaDataMutationResult getFunctions(PName tenantId, List<Pair<byte[], Long>> functionNameAndTimeStampPairs, long clientTimestamp) throws SQLException {
List<PFunction> functions = new ArrayList<PFunction>(functionNameAndTimeStampPairs.size());
for (Pair<byte[], Long> functionInfo : functionNameAndTimeStampPairs) {
try {
PFunction function2 = metaData.getFunction(new PTableKey(tenantId, Bytes.toString(functionInfo.getFirst())));
functions.add(function2);
} catch (FunctionNotFoundException e) {
return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND, 0, null);
}
}
if (functions.isEmpty()) {
return null;
}
return new MetaDataMutationResult(MutationCode.FUNCTION_ALREADY_EXISTS, 0, functions, true);
}
use of org.apache.phoenix.schema.FunctionNotFoundException in project phoenix by apache.
the class FunctionParseNode method validate.
public List<Expression> validate(List<Expression> children, StatementContext context) throws SQLException {
BuiltInFunctionInfo info = this.getInfo();
BuiltInFunctionArgInfo[] args = info.getArgs();
if (args.length < children.size() || info.getRequiredArgCount() > children.size()) {
throw new FunctionNotFoundException(this.name);
}
if (args.length > children.size()) {
List<Expression> moreChildren = new ArrayList<Expression>(children);
for (int i = children.size(); i < info.getArgs().length; i++) {
moreChildren.add(LiteralExpression.newConstant(null, args[i].allowedTypes.length == 0 ? null : PDataTypeFactory.getInstance().instanceFromClass(args[i].allowedTypes[0]), Determinism.ALWAYS));
}
children = moreChildren;
}
List<ParseNode> nodeChildren = this.getChildren();
for (int i = 0; i < children.size(); i++) {
BindParseNode bindNode = null;
Class<? extends PDataType>[] allowedTypes = args[i].getAllowedTypes();
// values.
if (i < nodeChildren.size() && nodeChildren.get(i) instanceof BindParseNode) {
bindNode = (BindParseNode) nodeChildren.get(i);
}
// If the child type is null, then the expression is unbound.
// Skip any validation, since we either 1) have a default value
// which has already been validated, 2) attempting to get the
// parameter metadata, or 3) have an unbound parameter which
// will be detected futher downstream.
Expression child = children.get(i);
if (child.getDataType() == null || /* null used explicitly in query */
i >= nodeChildren.size()) /* argument left off */
{
// Replace the unbound expression with the default value expression if specified
if (args[i].getDefaultValue() != null) {
Expression defaultValue = args[i].getDefaultValue();
children.set(i, defaultValue);
// Set the parameter metadata if this is a bind parameter
if (bindNode != null) {
context.getBindManager().addParamMetaData(bindNode, defaultValue);
}
} else if (bindNode != null) {
// based on the function argument annonation set the parameter meta data.
if (child.getDataType() == null) {
if (allowedTypes.length > 0) {
context.getBindManager().addParamMetaData(bindNode, LiteralExpression.newConstant(null, PDataTypeFactory.getInstance().instanceFromClass(allowedTypes[0]), Determinism.ALWAYS));
}
} else {
// Use expression as is, since we already have the data type set
context.getBindManager().addParamMetaData(bindNode, child);
}
}
} else {
validateFunctionArguement(info, i, child);
}
}
return children;
}
use of org.apache.phoenix.schema.FunctionNotFoundException in project phoenix by apache.
the class UserDefinedFunctionsIT method testUDFsWithMultipleConnections.
@Test
public void testUDFsWithMultipleConnections() throws Exception {
Connection conn1 = driver.connect(url, EMPTY_PROPS);
conn1.createStatement().execute("create function myfunction(VARCHAR) returns VARCHAR as 'org.apache.phoenix.end2end." + MY_REVERSE_CLASS_NAME + "' using jar " + "'" + util.getConfiguration().get(DYNAMIC_JARS_DIR_KEY) + "/myjar1.jar" + "'");
Connection conn2 = driver.connect(url, EMPTY_PROPS);
try {
conn2.createStatement().execute("create function myfunction(VARCHAR) returns VARCHAR as 'org.apache.phoenix.end2end." + MY_REVERSE_CLASS_NAME + "' using jar " + "'" + util.getConfiguration().get(DYNAMIC_JARS_DIR_KEY) + "/myjar1.jar" + "'");
fail("FunctionAlreadyExistsException should be thrown.");
} catch (FunctionAlreadyExistsException e) {
}
conn2.createStatement().execute("create table t8(k integer not null primary key, k1 integer, name varchar)");
conn2.createStatement().execute("upsert into t8 values(1,1,'jock')");
conn2.commit();
ResultSet rs = conn2.createStatement().executeQuery("select MYFUNCTION(name) from t8");
assertTrue(rs.next());
assertEquals("kcoj", rs.getString(1));
assertFalse(rs.next());
rs = conn2.createStatement().executeQuery("select * from t8 where MYFUNCTION(name)='kcoj'");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals(1, rs.getInt(2));
assertEquals("jock", rs.getString(3));
assertFalse(rs.next());
conn2.createStatement().execute("drop function MYFUNCTION");
try {
rs = conn1.createStatement().executeQuery("select MYFUNCTION(name) from t8");
fail("FunctionNotFoundException should be thrown");
} catch (FunctionNotFoundException e) {
}
}
Aggregations