postgresql中不存在函数min(uuid)

时间:2018-03-12 03:00:07

标签: postgresql sqoop

我使用sqoop将表格从Postgres导入到hdfs。我的表有uuid字段作为主键,我的命令sqoop如下:

sqoop import --connect 'jdbc:postgresql://localhost:5432/mydb' --username postgreuser --password 123456abcA --driver org.postgresql.Driver --table users --map-column-java id=String --target-dir /hdfs/postgre/users --as-avrodatafile --compress -m 2

但是我得到了错误:

Import failed: java.io.IOException: org.postgresql.util.PSQLException: ERROR: function min(uuid) does not exist

我尝试执行sql命令:SELECT min(id) from users并得到了同样的错误。我该怎么办呢?我使用Postgres 9.4,hadoop 2.9.0和sqoop 1.4.7

4 个答案:

答案 0 :(得分:3)

我想归功于@ robin-salih的答案,我已经将它和min的实现用于int来构建以下代码:

CREATE OR REPLACE FUNCTION min(uuid, uuid)
RETURNS uuid AS $$
BEGIN
    IF $2 IS NULL OR $1 > $2 THEN
        RETURN $2;
    END IF;

    RETURN $1;
END;
$$ LANGUAGE plpgsql;


create aggregate min(uuid) (
  sfunc = min,
  stype = uuid,
  combinefunc = min,
  parallel = safe,
  sortop = operator (<)
);

几乎相同,但是利用了B树索引,因此select min(id) from tbl可以在几毫秒内工作。

P.S。。我不是pgsql专家,也许我的代码有某种错误,请在生产中使用之前进行仔细检查,但我希望它能正确使用索引和并行执行。我只是通过示例代码来完成它,而不是深入研究PG中的聚合背后的理论。

答案 1 :(得分:1)

Postgres没有内置的最小/最大uuid功能,但是您可以使用以下代码创建自己的代码:

CREATE OR REPLACE FUNCTION min(uuid, uuid)
RETURNS uuid AS $$
BEGIN
    IF $2 IS NULL OR $1 > $2 THEN
        RETURN $2;
    END IF;

    RETURN $1;
END;
$$ LANGUAGE plpgsql;


CREATE AGGREGATE min(uuid)
(
    sfunc = min,
    stype = uuid
);

答案 2 :(得分:1)

我发现@ robin-salih和@ bodgan-mart提供的答案是一个很好的起点,但最终是不正确的。这是一个对我更好的解决方案:

    CREATE FUNCTION min_uuid(uuid, uuid)
    RETURNS uuid AS $$
    BEGIN
        -- if they're both null, return null
        IF $2 IS NULL AND $1 IS NULL THEN
            RETURN NULL ;
        END IF;

        -- if just 1 is null, return the other
        IF $2 IS NULL THEN
            RETURN $1;
        END IF ;
        IF $1 IS NULL THEN
            RETURN $2;
          END IF;

        -- neither are null, return the smaller one
        IF $1 > $2 THEN
            RETURN $2;
        END IF;

        RETURN $1;
    END;
    $$ LANGUAGE plpgsql;


    create aggregate min(uuid) (
      sfunc = min_uuid,
      stype = uuid,
      combinefunc = min_uuid,
      parallel = safe,
      sortop = operator (<)
    );

有关更多详细信息,请参阅我在How to select minimum UUID with left outer join?上的帖子

答案 3 :(得分:-1)

这不是sqoop的问题。 Postgres不允许在uuid上使用min / max。每个uuid都是独一无二的,不会被认为比其他更大/更小。

要在sqoop中修复此问题,您可能需要使用其他字段作为拆分键。我使用created_At时间戳作为我的拆分键。