PostgreSQL函数返回任意类型

时间:2012-05-13 12:31:50

标签: sql postgresql plpgsql plv8

有没有办法让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';

返回count字段的位置&lt; = 10.但是,如果字段不是数字,则会失败。 我不想为我的json可能拥有的每种类型的数据创建一个特定的函数,是否有办法以某种方式推断数据类型并隐式转换?

另见How do I query using fields inside the new PostgreSQL JSON datatype?

1 个答案:

答案 0 :(得分:3)

您似乎在寻找Polymorphic types的功能 阅读以上关于类型的部分以及this section中的最后两个示例。

注意,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的类型与所需的返回类型不同。