blob: 89552da69ebbda6139b1d15e89ff944723070d95 [file] [log] [blame]
/**
* 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 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.apache.ranger.authorization.hive.udf;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hive.common.type.HiveChar;
import org.apache.hadoop.hive.common.type.HiveVarchar;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject;
import org.apache.hadoop.hive.serde2.io.*;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.*;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import java.sql.Date;
public abstract class RangerBaseUdf extends GenericUDF {
private static final Log LOG = LogFactory.getLog(RangerBaseUdf.class);
final protected AbstractTransformer transformer;
final protected String displayName;
protected AbstractTransformerAdapter transformerAdapter = null;
protected RangerBaseUdf(AbstractTransformer transformer, String displayName) {
this.transformer = transformer;
this.displayName = displayName;
}
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
LOG.debug("==> RangerBaseUdf.initialize()");
checkArgPrimitive(arguments, 0); // first argument is the column to be transformed
PrimitiveObjectInspector columnType = ((PrimitiveObjectInspector) arguments[0]);
transformer.init(arguments, 1);
transformerAdapter = AbstractTransformerAdapter.getTransformerAdapter(columnType, transformer);
ObjectInspector ret = PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(columnType.getPrimitiveCategory());
LOG.debug("<== RangerBaseUdf.initialize()");
return ret;
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
Object ret = transformerAdapter.getTransformedWritable(arguments[0]);
return ret;
}
@Override
public String getDisplayString(String[] children) {
return getStandardDisplayString(displayName, children);
}
}
/**
* Interface to be implemented by transformers which transform a given value according to its specification.
*/
abstract class AbstractTransformer {
/**
* Initialzie the transformer object
* @param arguments arguments given to GenericUDF.initialzie()
* @param startIdx index into array, from which the transformer should read values
*/
abstract void init(ObjectInspector[] arguments, int startIdx);
/**
* Transform a String value
* @param value value to transform
* @return transformed value
*/
abstract String transform(String value);
/**
* Transform a Byte value
* @param value value to transform
* @return transformed value
*/
abstract Byte transform(Byte value);
/**
* Transform a Short value
* @param value value to transform
* @return transformed value
*/
abstract Short transform(Short value);
/**
* Transform a Integer value
* @param value value to transform
* @return transformed value
*/
abstract Integer transform(Integer value);
/**
* Transform a Long value
* @param value value to transform
* @return transformed value
*/
abstract Long transform(Long value);
/**
* Transform a Date value
* @param value value to transform
* @return transformed value
*/
abstract Date transform(Date value);
}
/**
* Interface to be implemented by datatype specific adapters that handle necessary conversion of the transformed value
* into appropriate Writable object, which GenericUDF.evaluate() is expected to return.
*/
abstract class AbstractTransformerAdapter {
final AbstractTransformer transformer;
AbstractTransformerAdapter(AbstractTransformer transformer) {
this.transformer = transformer;
}
abstract Object getTransformedWritable(DeferredObject value) throws HiveException;
static AbstractTransformerAdapter getTransformerAdapter(PrimitiveObjectInspector columnType, AbstractTransformer transformer) {
final AbstractTransformerAdapter ret;
switch(columnType.getPrimitiveCategory()) {
case STRING:
ret = new StringTransformerAdapter((StringObjectInspector)columnType, transformer);
break;
case CHAR:
ret = new HiveCharTransformerAdapter((HiveCharObjectInspector)columnType, transformer);
break;
case VARCHAR:
ret = new HiveVarcharTransformerAdapter((HiveVarcharObjectInspector)columnType, transformer);
break;
case BYTE:
ret = new ByteTransformerAdapter((ByteObjectInspector)columnType, transformer);
break;
case SHORT:
ret = new ShortTransformerAdapter((ShortObjectInspector)columnType, transformer);
break;
case INT:
ret = new IntegerTransformerAdapter((IntObjectInspector)columnType, transformer);
break;
case LONG:
ret = new LongTransformerAdapter((LongObjectInspector)columnType, transformer);
break;
case DATE:
ret = new DateTransformerAdapter((DateObjectInspector)columnType, transformer);
break;
default:
ret = new UnsupportedDatatypeTransformAdapter(columnType, transformer);
break;
}
return ret;
}
}
class ByteTransformerAdapter extends AbstractTransformerAdapter {
final ByteObjectInspector columnType;
final ByteWritable writable;
public ByteTransformerAdapter(ByteObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new ByteWritable());
}
public ByteTransformerAdapter(ByteObjectInspector columnType, AbstractTransformer transformer, ByteWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
Byte value = (Byte)columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
Byte transformedValue = transformer.transform(value);
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class DateTransformerAdapter extends AbstractTransformerAdapter {
final DateObjectInspector columnType;
final DateWritable writable;
public DateTransformerAdapter(DateObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new DateWritable());
}
public DateTransformerAdapter(DateObjectInspector columnType, AbstractTransformer transformer, DateWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
Date value = columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
Date transformedValue = transformer.transform(value);
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class HiveCharTransformerAdapter extends AbstractTransformerAdapter {
final HiveCharObjectInspector columnType;
final HiveCharWritable writable;
public HiveCharTransformerAdapter(HiveCharObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new HiveCharWritable());
}
public HiveCharTransformerAdapter(HiveCharObjectInspector columnType, AbstractTransformer transformer, HiveCharWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
HiveChar value = columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
String transformedValue = transformer.transform(value.getValue());
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class HiveVarcharTransformerAdapter extends AbstractTransformerAdapter {
final HiveVarcharObjectInspector columnType;
final HiveVarcharWritable writable;
public HiveVarcharTransformerAdapter(HiveVarcharObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new HiveVarcharWritable());
}
public HiveVarcharTransformerAdapter(HiveVarcharObjectInspector columnType, AbstractTransformer transformer, HiveVarcharWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
HiveVarchar value = columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
String transformedValue = transformer.transform(value.getValue());
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class IntegerTransformerAdapter extends AbstractTransformerAdapter {
final IntObjectInspector columnType;
final IntWritable writable;
public IntegerTransformerAdapter(IntObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new IntWritable());
}
public IntegerTransformerAdapter(IntObjectInspector columnType, AbstractTransformer transformer, IntWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
Integer value = (Integer)columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
Integer transformedValue = transformer.transform(value);
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class LongTransformerAdapter extends AbstractTransformerAdapter {
final LongObjectInspector columnType;
final LongWritable writable;
public LongTransformerAdapter(LongObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new LongWritable());
}
public LongTransformerAdapter(LongObjectInspector columnType, AbstractTransformer transformer, LongWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
Long value = (Long)columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
Long transformedValue = transformer.transform(value);
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class ShortTransformerAdapter extends AbstractTransformerAdapter {
final ShortObjectInspector columnType;
final ShortWritable writable;
public ShortTransformerAdapter(ShortObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new ShortWritable());
}
public ShortTransformerAdapter(ShortObjectInspector columnType, AbstractTransformer transformer, ShortWritable writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
Short value = (Short)columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
Short transformedValue = transformer.transform(value);
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class StringTransformerAdapter extends AbstractTransformerAdapter {
final StringObjectInspector columnType;
final Text writable;
public StringTransformerAdapter(StringObjectInspector columnType, AbstractTransformer transformer) {
this(columnType, transformer, new Text());
}
public StringTransformerAdapter(StringObjectInspector columnType, AbstractTransformer transformer, Text writable) {
super(transformer);
this.columnType = columnType;
this.writable = writable;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
String value = columnType.getPrimitiveJavaObject(object.get());
if(value != null) {
String transformedValue = transformer.transform(value);
if(transformedValue != null) {
writable.set(transformedValue);
return writable;
}
}
return null;
}
}
class UnsupportedDatatypeTransformAdapter extends AbstractTransformerAdapter {
final PrimitiveObjectInspector columnType;
public UnsupportedDatatypeTransformAdapter(PrimitiveObjectInspector columnType, AbstractTransformer transformer) {
super(transformer);
this.columnType = columnType;
}
@Override
public Object getTransformedWritable(DeferredObject object) throws HiveException {
return null;
}
}