Имеет ли NULLIF в Hive известную проблему реализации в определенных версиях? - PullRequest
0 голосов
/ 11 февраля 2020

Я использую EMR 5.19 Hive 2.3.3, и у меня возникла проблема с тем, что Nullif не преобразовывает из Java String в Had oop Text или наоборот. Источник: CloudTrail Serde От AWS, кажется, написано твердо. Похоже, что проблема связана со встроенной UUF NULLIF, как вы можете прочитать в сообщении об ошибке:

Я проверяю, является ли результат извлечения регулярного выражения пустой строкой, и если да, то я хотел бы получить нулевое значение, поэтому моя колонка выглядит немного как NULLIF(REGEXP_EXTRACT(key,'([^\/]+)(\/\d+)?(\/.*)', 1), '') AS key_prefix Но я получаю ошибки, как показано ниже:

2020-02-11 11:06:34,034 INFO [IPC Server handler 26 on 43627] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Diagnostics report from attempt_1574116917806_1754132_r_000008_3: Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Error evaluating NULLIF(regexp_extract(_col2, '(^[^\/]*)\/(\d\/)?([^\/][^\/]+)', 1),'')
    at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:257)
    at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:445)
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:393)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:175)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1844)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:169)
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Error evaluating NULLIF(regexp_extract(_col2, '(^[^\/]*)\/(\d\/)?([^\/][^\/]+)', 1),'')
    at org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:93)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:897)
    at org.apache.hadoop.hive.ql.exec.CommonJoinOperator.internalForward(CommonJoinOperator.java:820)
    at org.apache.hadoop.hive.ql.exec.CommonJoinOperator.genUniqueJoinObject(CommonJoinOperator.java:834)
    at org.apache.hadoop.hive.ql.exec.CommonJoinOperator.genUniqueJoinObject(CommonJoinOperator.java:837)
    at org.apache.hadoop.hive.ql.exec.CommonJoinOperator.checkAndGenObject(CommonJoinOperator.java:938)
    at org.apache.hadoop.hive.ql.exec.JoinOperator.endGroup(JoinOperator.java:264)
    at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:196)
    ... 7 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.hadoop.io.Text
    at org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableStringObjectInspector.getPrimitiveWritableObject(WritableStringObjectInspector.java:41)
    at org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils.comparePrimitiveObjects(PrimitiveObjectInspectorUtils.java:421)
    at org.apache.hadoop.hive.ql.udf.generic.GenericUDFNullif.evaluate(GenericUDFNullif.java:93)

Ответы [ 2 ]

0 голосов
/ 12 февраля 2020

Замена NULLIF макросом, который делает то, что говорит NULLIF, избегает исключений и работает так же хорошо:

CREATE TEMPORARY MACRO NULLIFY(s string) if(s = '', null, s);
SELECT
  NULLIFY(REGEXP_EXTRACT(LSRC.key, '(^[^\\/]*)\\/(\\d\\/)?([^\\/][^\\/]+)', 1)) AS a_schema_name,
  NULLIFY(REGEXP_EXTRACT(LSRC.key, '(^[^\\/]*)\\/(\\d\\/)?([^\\/][^\\/]+)', 3)) AS a_table_name,
  NULLIFY(REGEXP_EXTRACT(LSRC.key, '(^[^/]*)/(\\d/)?([^/][^/]+)', 1)) AS b_schema_name,
  NULLIFY(REGEXP_EXTRACT(LSRC.key, '(^[^/]*)/(\\d/)?([^/][^/]+)', 3)) AS b_table_name,
  NULLIFY(REGEXP_EXTRACT(LSRC.key, "(^[^/]*)/(\d/)?([^/][^/]+)", 1)) AS c_schema_name,
  NULLIFY(REGEXP_EXTRACT(LSRC.key, "(^[^/]*)/(\d/)?([^/][^/]+)", 3)) AS c_table_name,
  NULLIFY(LSRC.key) AS key
FROM (SELECT 'db/1/table/part/file' key) LSRC;

Результат:

db      table   db      table   NULL    NULL    db/1/table/part/file

В то время как с соответствующая строка:

NULL    NULL    NULL    NULL    NULL    NULL    non-matching

Вместо неудобного результата с пустыми строками

                                                db/1/table/part/file
0 голосов
/ 11 февраля 2020

Возможно, нет прямого ответа на ваш вопрос, но надеюсь, что это поможет.

  1. regexp_extract возвращает пустую строку '', если регулярное выражение не совпадает, оно может вернуть null, только если исходная строка null. Таким образом, использование NULLIF здесь выглядит некорректно
  2. Используйте двойную обратную косую черту sh для экранирования специальных символов, таких как \\d в регулярном выражении Hive.
  3. / - не является специальным символом и не нуждается в экранирование / экранирование.

Я бы предложил макрос, подобный этому:

CREATE TEMPORARY MACRO normalize_null(s string) CASE WHEN s!='' THEN s END;

Он преобразует пустые строки в нули, NULL и все остальное как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...