3

有没有办法让 PostgreSQL 中的函数返回任意类型?

我正在尝试使用 PLV8 从 PostgreSQL 9.2 中的 JSON 类型中获取和比较字段。

以下作品:

CREATE or replace FUNCTION jn (j json, key any ) RETURNS numeric 
LANGUAGE plv8   
IMMUTABLE 
AS $function$  
  var ej = JSON.parse(j);   
  if (typeof ej != 'object') return NULL;   
  return JSON.stringify(ej[key]);  
$function$;

SELECT * FROM things WHERE jn(data,'count') <= '10';

返回计数字段<= 10的位置。但是,如果该字段不是数字,它将失败。我不想为我的 json 可能持有的每种类型的数据创建一个特定的函数,有没有办法以某种方式推断数据类型并隐式转换?

另请参阅如何使用新 PostgreSQL JSON 数据类型中的字段进行查询?

4

1 回答 1

4

您似乎正在寻找具有多态类型的函数。
阅读上面关于类型的部分和本节中的最后 2 个示例。

请注意,key参数的类型和函数的输出应该匹配。如果这不是您的情况,那么您可能应该返回text然后将其转换为函数外部的正确类型。

我认为这将为您完成工作:

CREATE or replace FUNCTION jn (j json, key anyelement ) RETURNS anyelement
LANGUAGE plv8   
IMMUTABLE 
AS $function$  
  var ej = JSON.parse(j);   
  if (typeof ej != 'object') return NULL;   
  return JSON.stringify(ej[key]);  
$function$;

抱歉,我周围没有 9.2 服务器,所以我无法对此进行测试。


编辑:

事情是——在你能够在函数中执行任何强制转换之前,必须先创建它。在创建时函数的输入参数的类型和返回类型是固定的。这意味着您只有两种可能性:

  • 使用anyelement类型,这将强制您拥有key与您希望从函数返回的类型相同的参数;
  • 在函数外使用text类型和强制转换结果。

由于PLV8还不支持anyelement类型,您实际上可以在 PL/pgSQL 上创建一个包装函数来为您完成这项工作:

CREATE FUNCTION jn_wrap(jn varchar, key anyelement, OUT ret anyelement)
    AS $js_wrap$
BEGIN
    EXECUTE 'SELECT CAST(jn($1, $2) AS '||pg_typeof(key)||')'
        USING jn, key INTO ret;

    RETURN ;
END;
$js_wrap$ LANGUAGE plpgsql;

尽管我认为这可能很典型,但它key的类型将与所需的返回类型不同。

于 2012-05-13T12:46:39.520 回答