Как проверить, является ли данный текстовый столбец допустимым oid - PullRequest
0 голосов
/ 05 декабря 2018

В PL / pgSQL у меня есть столбец, который может содержать или не содержать oid.Мне нужно определить, делает это или нет.

В данный момент я делаю это так:

  select oidtext from t into x where name = fname;
  if found then
    begin
        select x::oid into looid;
    exception
        when SQLSTATE '22P02' then -- invalid oid    
           null;

, но это выглядит немного хакерским.Есть ли положительный тест, т. Е. «Является ли этот текстовый столбец допустимым типом x» или «это допустимый приведение»?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Моему решению не нужно регистрировать ошибки:

CREATE FUNCTION is_oid(text) RETURNS boolean
   LANGUAGE sql IMMUTABLE STRICT AS
$$SELECT CASE WHEN trim(leading '0' from $1) ~ '^\d{1,10}$'
              THEN $1::bigint BETWEEN 0 AND 4294967295
              ELSE FALSE
         END$$;

oid - это 4-байтовое целое число без знака, поэтому оно должно состоять не более чем из 10 цифр и быть в диапазоне от 0 до 4294967295.

0 голосов
/ 05 декабря 2018

Кажется, что единственный способ - перехватить исключение, но вы можете сделать это с помощью удобной функции, подобной этой:

create or replace function oid_or_null(text)
returns oid language plpgsql immutable as $$
begin
    return $1::oid;
exception when invalid_text_representation then
    return null;
end $$;

select oid_or_null('123'), oid_or_null('abc');

 oid_or_null | oid_or_null 
-------------+-------------
         123 |            
(1 row) 

Вы можете создать более общую логическую функцию:

create or replace function is_valid_cast(text, text)
returns boolean language plpgsql immutable as $$
begin
    execute format('select %L::%I', $1, $2);
    return true;
exception when others then
    return false;
end $$;

select 
    is_valid_cast('123', 'oid') as oid, is_valid_cast('abc', 'oid') as not_oid,
    is_valid_cast('2018-10-10', 'date') as date, is_valid_cast('2018-20-20', 'date') as not_date;

 oid | not_oid | date | not_date 
-----+---------+------+----------
 t   | f       | t    | f
(1 row)     
...