hive - 具有不同关键字的查询和子查询在带有 udf 的 Hive 中不起作用
问题描述
不工作查询:selectlookup(city, state, tax,'addresslookup') from (select distinct city, state, tax from open_glory.addylookup) a
工作查询(没有不同):
select lookup(city, state, tax,'addresslookup') from (select city, state, tax from open_glory.addylookup)
任何帮助,将不胜感激。
UDF 代码:
Not working Query :
select lookup(city, state, tax,'addresslookup') from (select distinct city, state, tax from open_glory.addylookup) a
工作查询(没有不同):
select lookup(city, state, tax,'addresslookup') from (select city, state, tax from open_glory.addylookup)
任何帮助,将不胜感激。
UDF 代码:
public class Lookup extends GenericUDF {
private static String delimiter = "|";
private ConcurrentHashMap < String, HashMap < String, String >> fileMap = new ConcurrentHashMap < String, HashMap < String, String >> ();
protected String loggedInUser;
protected String loggedInApplication;
private transient GenericUDFUtils.StringHelper returnHelper;
private transient StringConverter[] stringConverter;
private static final Logger LOG = LoggerFactory.getLogger(Lookup.class.getName());
@Override
public ObjectInspector initialize(ObjectInspector[] arguments)
throws UDFArgumentException {
if (arguments.length < 2) {
throw new UDFArgumentLengthException(
"lookup takes 2 or more arguments");
}
stringConverter = new StringConverter[arguments.length];
for (int i = 0; i < arguments.length; i++) {
if (arguments[0].getCategory() != Category.PRIMITIVE) {
throw new UDFArgumentException(
"lookup only takes primitive types");
}
stringConverter[i] = new PrimitiveObjectInspectorConverter.StringConverter(
(PrimitiveObjectInspector) arguments[i]);
}
setLoggedInUser();
returnHelper = new GenericUDFUtils.StringHelper(
PrimitiveCategory.STRING);
LOG.info("initialize successful");
return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
}
private void setLoggedInUser() {
if (loggedInUser == null) {
loggedInUser = SessionState.get().getUserName();
if (loggedInUser != null) {
int idx = loggedInUser.indexOf('.');
loggedInApplication = idx > -1 ? loggedInUser.substring(0, idx) : null;
}
}
}
private void initMap(String f) {
LOG.info("initMap involked");
if (loggedInApplication == null)
throw new NullPointerException(
"Unable to retrieve application name from user.");
String filePath = "/basepath/" + loggedInApplication.toLowerCase() + "/" + f +
".txt";
String line = null;
try {
LOG.info("filePath =" + filePath);
FileSystem fs = FileSystem.get(new Configuration());
FSDataInputStream in = fs.open(new Path(filePath));
BufferedReader br = new BufferedReader(new InputStreamReader( in ));
HashMap < String, String > map = new HashMap < String, String > ();
while ((line = br.readLine()) != null) {
// ignore comment lines
if (line.startsWith("#")) {
continue;
}
String[] strs = line.split("\t");
if (strs.length == 2) {
map.put(strs[0].toUpperCase().trim(), strs[1].trim());
} else if (strs.length > 2) {
map.put(getKey(strs), strs[strs.length - 1].trim());
}
}
fileMap.put(f, map);
br.close();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
public Text getValue(String s, String f) {
initMap(f);
HashMap < String, String > map = fileMap.get(f);
LOG.info("getValue() fileMap =" + fileMap);
String v = map.get(s);
return v == null ? null : new Text(v);
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
String val = buildVal(arguments);
String lookupFile = (String) stringConverter[arguments.length - 1].convert(arguments[arguments.length - 1].get());
Text returnVal = getValue(val.toUpperCase(), lookupFile.toLowerCase());
return returnVal == null ? null : returnHelper.setReturnValue(returnVal.toString());
}
@Override
public String getDisplayString(String[] arg0) {
return "lookup()";
}
private String buildVal(DeferredObject[] arguments) throws HiveException {
StringBuilder builder = new StringBuilder();
int cnt = arguments.length - 1;
for (int i = 0; i < cnt; i++) {
builder.append((String) stringConverter[i].convert(arguments[i].get()));
if (i < cnt - 1) {
builder.append(delimiter);
}
}
return builder.toString();
}
private String getKey(String[] strs) {
StringBuilder builder = new StringBuilder();
int cnt = strs.length - 1;
for (int i = 0; i < cnt; i++) {
builder.append(strs[i].toUpperCase().trim());
if (i < cnt - 1) {
builder.append(delimiter);
}
}
return builder.toString();
}
}
解决方案
推荐阅读
- json - 有没有办法在 JMeter 的一个断言中添加多个验证?
- swift - 如何让用户向我的应用程序添加附件,例如 pdf 或 jpg,然后如何将其存储在我的领域数据库中?
- python - 我可以在 Django 中使用 Textarea 作为 modelformset 的表单吗?
- spring - 如何使用 Spring Boot 向 Whatsapp 发送消息?
- javascript - 我可以获得格式化我未来日期 javascript 的帮助吗?
- javascript - 使用 Apache 运行服务器端 Javascript
- css - 如何防止我的图片在 CSS 中溢出?
- build - Netlify 在构建时部署问题
- python - Python从zip中提取文件
- python - 一系列列表的元素随机选择(没有循环)