当前位置: 首页 > 知识库问答 >
问题:

查询java UDF生成的数据时产生的错误

寿亦
2023-03-14

首先,我的目标不是让您理解我的UDF代码,这样我就可以实现我的目标(我知道它实现了),而是了解为什么在以后的查询中调用它生成的字符串后会出现错误。

我做了一个自定义UDF,代码是:

import java.util.HashMap;

import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.udf.UDFType;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;

public class Calculate_states extends UDF
{

        HashMap<String, Long> last_ts = 
                new HashMap<String, Long>();

        HashMap<String, Integer> last_val = 
                new HashMap<String, Integer>();

        HashMap<String, Long> ts_last_start = 
                new HashMap<String, Long>();

        HashMap<String, String> start_type = 
                new HashMap<String, String>();


  public  String evaluate( Integer bit,  Long ts,  Long next_ts, Integer next_bit, Integer time, String Ut)
  {

    Object[] result = new Object[4];
    String estado = new String();

    if(bit==null)
    {
        result[0]=new Text("no state");

    }
    else 

    {
        if(bit==1 && (

                    (
                    ( next_ts == null ||  ((next_ts-ts)/1000) > time )
                    &&
                    ( last_ts.get(Ut) == null  || ((ts-last_ts.get(Ut))/1000) > time  ) 
                    )

                    ||
                    (
                    (last_val.get(Ut)!=null) && 
                    last_val.get(Ut)==0 && ((ts-last_ts.get(Ut))/1000) <=time && 
                        (next_ts == null ||
                        (next_ts-ts)/1000 > time)
                    )
                    ||
                    (
                            (next_bit!=null) && // Condición necesaria para no entrar en problemas con los nulls
                            (       next_bit==0 && ((next_ts-ts)/1000) <= time && 
                            (   (last_ts.get(Ut) == null ||
                                ((ts-last_ts.get(Ut))/1000) > time )

                            )
                            )
                    )
                    )
                )
             { estado= "isolated point";
            result[0]=new Text("isolated point");}

        else if 
    (

            bit==1 && 
            (
            last_val.get(Ut) != null && // Para evitar problemas de nulls
            last_val.get(Ut)==0 && ((ts-last_ts.get(Ut))/1000 ) <=time)
    ){  estado= "start";
        result[0]=new Text("start");}

    else if 
    (
            bit==0 && 
            ( last_val.get(Ut) != null && // Para evitar problemas de nulls
            last_val.get(Ut)==1 && ((ts-last_ts.get(Ut))/1000 ) <=time )
    ){estado= "stop";
        result[0]=new Text("stop");}    
    else if 
    (
            bit==1 && (last_ts.get(Ut)==null ||  ((ts-last_ts.get(Ut))/1000 ) > time  )
    ){estado= "no info start";
        result[0]=new Text("no info start");}
     else if 
    (
            bit==1 && (next_bit==null || ((next_ts-ts)/1000 ) > time  )
    ){estado= "no info stop";
        result[0]=new Text("no info stop");} 
    else if
    (bit==1 ){
        result[0]=new Text("working");}
    else if
    (bit==0 ){
        result[0]=new Text("stopped");}
        // Actualizar valores
        last_val.put(Ut,bit);
        last_ts.put(Ut,ts);
    }

    if (estado.equals("isolated point"))
    { result[1]= new LongWritable(1);
    // Podria ser freq. muestreo, nuevo parametro
    result[2]= new Text("isolated point");
      result[3]= new LongWritable(ts);
    } 

    else if ( 
     estado.equals("start") || 
     estado.equals("no info start")
      ){
        ts_last_start.put(Ut,ts);
        start_type.put(Ut,estado);
        //result[2]=null;
        result[3]=new LongWritable(ts);
        }
    else if ( 
            estado.equals("stop") || 
            estado.equals("no info stop")
              ){
                result[3]=new LongWritable(ts_last_start.get(Ut));
                result[1]= new LongWritable((ts-ts_last_start.get(Ut))/1000);
                result[2]= new Text(start_type.get(Ut)+"-"+estado); 
                ts_last_start.put(Ut,null);
                }
    else 
        //result[2]=null;
        if (ts_last_start.get(Ut) == null)
        {
            result[3] =null;
        }
        else
        result[3]=new LongWritable(ts_last_start.get(Ut));

    String resultado="";
    for (int i=0;i<4;i++)
    {
    if (i==3)
    resultado=resultado+String.valueOf(result[i]);
    else
        resultado=resultado+String.valueOf(result[i])+";";
    }

    return resultado;
  }
}

它的目标是计算组件的状态(它开始工作、停止工作的位置),并在开始和停止之间的所有行中放置一个标识符。1/0意味着工作/不工作组件。

例如,这个问题:

select 
ut,ts, bit, 
calculate_states(bit,ts,if (bit is null, null,next_ts),next_bit,1,ut) as states
from 
(
select 
ut,
ts,
bit, -- Means component bit
last_value(bit ignore nulls) over (partition by ut order by ts desc rows between 1 preceding and 1 preceding) as next_bit,
min(if (bit is not null, ts, null)) over (partition by ut order by ts desc rows between unbounded preceding and 1 preceding) as next_ts
from my_table
order by 1,2
)b
order by 1,2;

将返回(在此表中):

UT  |  ts  |  bit |   States
a     1000     0      stopped;null;null;null
a     2000     0      stopped;null;null;null
a     3000     0      stopped;null;null;null
a     4000     1      start;null;null;4000
a     5000     1      no info stop;2;start-no info stop;4000
a     6000     null   no state;null;null;null
a     7000     1      no info start;null;null;7000
a     8000     1      working;null;null;7000
a     9000     0      stop;3;no info start-stop;7000
a     10000    1      start;null;null;10000
a     11000    1      working;null;null;10000
a     12000    1      no info stop;3;start-no info stop;10000

直到这里都是正确的。现在,我只是补充一句

按ut、ts从查询顺序中选择*

创建表格new_table as QUERY,并按ut、ts从新_table order中选择*

在我的日志中出现此错误后:

UDF WARNING: Hive UDF path=hdfs://mypath class=UDFpackImpala.Calculate_states failed due to: ImpalaRuntimeException: UDF::evaluate() ran into a problem.
CAUSED BY: ImpalaRuntimeException: UDF failed to evaluate
CAUSED BY: InvocationTargetException: null
CAUSED BY: NullPointerException: null

我的结果会切换到我之前标记的那个

UT  |  ts  |  bit |   States
a     1000     0      stopped;null;null;null
a     2000     0      stopped;null;null;null
a     3000     0      NULL
a     4000     1      stop;null;null;4000
a     5000     1      working;null;null;null
a     6000     null   start;null;null;null
a     7000     1      working;null;null;null
a     8000     1      working;null;null;null
a     9000     0      stop;-1;no info start-stop;10000
a     10000    1      start;null;null;10000
a     11000    1      working;null;null;10000
a     12000    1      isolated point;1;null;12000

完全是随机的。我的问题是,为什么?

黑斑羚版本是:2.9.0-cdh5.12.2

共有1个答案

惠凯歌
2023-03-14

这一切都是因为如果不包含限制,impala不尊重第一个select中的order by子句。

如果你在第一个订单后999999999991,2,问题就解决了。

 类似资料:
  • 有人知道为什么这么简单的查询会出现两个错误吗?错误消息是: 警告:mysqli::准备():无法获取mysqli在(...)/functions.php行503 致命错误:在第504行的(…)functions.php中调用null上的成员函数bind_param()

  • 我试图在Spring Data JPA存储库中实现一个自定义方法。

  • 我有一张这样的桌子- 因此,我有一个特殊的数据类型()用于。 原始select查询如下所示- 结果是- 我想在带有查询生成器的Laravel中使用它,以便()这2个点可以来自用户输入。 我所做的是- 但它不起作用。 有人能帮忙吗?

  • 我正在使用Laravels查询生成器检索带有一些筛选选项的项目列表-我需要在此查询中进行计数: 计算“Freestyle ID”在likes表中出现的次数。 这有可能吗?返回的数据是完美的,我只需要一个自由泳的喜欢量,其中喜欢表中的自由泳ID为空。

  • 我做了一个实验...两个Spring数据存储库的一个公共实体:-jpa-mongoDB 首先,我使用以下库版本: 发布spring-data-jpa:1.7.0.发布spring-data-mongodb:1.6.0.发布 我觉得这是个很普通的案子。为什么Spring数据不能生成一样长的实体id?太奇怪了。

  • 问题内容: 在Sql Server Management Studio中,一旦我浏览了多维数据集,便可以删除列字段,行字段和过滤器字段。这将显示所需的数据。 我想知道是否有一种方法可以查看在后台生成的MDX查询以显示数据吗? 谢谢。 问题答案: SQL Server Profiler可在SSAS服务器上使用。启动Profiler连接时,在“连接”对话框中为“服务器”类型选择Analysis Ser