Postgres SELECT, где WHERE - UUID или строка

У меня есть следующая упрощенная таблица в Postgres:

  • Модель пользователя
    • идентификатор (UUID)
    • UID (VARCHAR)
    • имя (варчар)

Я хотел бы запрос, который может найти пользователя либо по его id UUID или его текстовый uid.

SELECT * FROM user
WHERE id = 'jsdfhiureeirh' or uid = 'jsdfhiureeirh';

Мой запрос генерирует invalid input syntax for uuid поскольку в этом случае я, очевидно, не использую UUID.

Как мне отшлифовать этот запрос или проверить, является ли значение допустимым UUID?

Ответ 1

Нашел! Передача столбца UUID в ::text останавливает ошибку. Не уверен в производительности, но примерно на 5000 строк я получаю более чем адекватную производительность.

SELECT * FROM user
WHERE id::text = 'jsdfhiureeirh' OR uid = 'jsdfhiureeirh';

SELECT * FROM user
WHERE id::text = '33bb9554-c616-42e6-a9c6-88d3bba4221c' 
  OR uid = '33bb9554-c616-42e6-a9c6-88d3bba4221c';

Ответ 2

Я изначально неправильно понял вопрос. Если вы хотите "безопасно" попытаться наложить строку на UUID, вы можете написать функцию, чтобы поймать исключение invalid_text_representation и просто вернуть null (измененный из ответа на другой вопрос):

CREATE OR REPLACE FUNCTION uuid_or_null(str text)
RETURNS uuid AS $$
BEGIN
  RETURN str::uuid;
EXCEPTION WHEN invalid_text_representation THEN
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

SELECT uuid_or_null('INVALID') IS NULL затем приведет к true.

Другими словами (учитывая, что (true or null) = true),

SELECT * FROM user
WHERE id = uuid_or_null('FOOBARBAZ') OR uid = 'FOOBARBAZ';

Оригинальный ответ:

Postgres автоматически преобразует строку в UUID для вас, но вам нужно использовать действительный UUID. Например:

SELECT * FROM user
WHERE id = '5af75c52-cb8e-44fb-93c8-1d46da518ee6' or uid = 'jsdfhiureeirh';

Вы также можете позволить Postgres генерировать UUID для вас с помощью предложения DEFAULT с помощью функции uuid_generate_v4() с помощью расширения uuid-ossp:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE user (  
   id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
   uid TEXT,
   name TEXT
);

Ответ 3

Вы можете проверить с помощью регулярного выражения:

SELECT *
FROM user
WHERE ('jsdfhiureeirh' ~ E'^[[:xdigit:]]{8}-([[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$'
       AND id = 'jsdfhiureeirh')
      OR uid = 'jsdfhiureeirh';