демо: дб <> скрипка
Вы можете поместить следующий код в функцию:
WITH byte AS ( -- 1
SELECT E'\\xDEADBEEF'::bytea as value
)
SELECT
string_agg( -- 5
get_byte(value, gs)::bit(8)::text -- 4
, ''
)
FROM
byte,
generate_series( -- 3
0,
length(value) - 1 -- 2
) gs
Я продемонстрировал разработку запроса в скрипке.
- Предложение
WITH
инкапсулирует значение bytea
для двойного использования в следующем коде
length()
вычисляет двоичную длину значения bytea
generate_series()
создает список от 0
до length - 1
(0 - 3
в моем примере)
get_byte()
принимает значение bytea
во второй раз и выдает байт в позиции gs
(предыдущие вычисленные значения 0-3
). Это дает integer
представление байта. После этого приведение к типу bit(8)
преобразует результат этой функции в ее двоичное представление (1 байт = 8 бит)
string_agg()
наконец-то объединяет все двоичные строки в одну. (принимает его text
представления вместо bit
типа, без разделителей)
Функция может выглядеть так:
CREATE OR REPLACE FUNCTION to_bit(value bytea) RETURNS SETOF text AS
$$
BEGIN
RETURN QUERY
SELECT
string_agg(get_byte(value, gs)::bit(8)::text, '')
FROM
generate_series(0, length(value) - 1) gs;
END;
$$ LANGUAGE plpgsql;
После этого вы можете назвать это:
SELECT to_bit(E'\\xDEADBEEF'::bytea)
Вы можете попробовать это, используя get_bit()
вместо get_byte()
. Это обезопасит вас от применения ::bit(8)
, но, конечно, вам нужно умножить длину на коэффициент 8
.
Полученная битовая строка имеет другой битовый порядок, но, возможно, она лучше подходит для вашего варианта использования:
WITH byte AS (
SELECT E'\\xDEADBEEF'::bytea as value
)
SELECT
string_agg(get_bit(value, gs)::text, '')
FROM
byte,
generate_series(0, length(value) * 8 - 1) gs
демо: дб <> скрипка