Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 15 additions & 31 deletions db/ptr.sql
Original file line number Diff line number Diff line change
@@ -1,36 +1,20 @@
-- Reverse DNS name of an address. Plain SQL (no STRICT, no sub-SELECT, only
-- immutable functions) so Postgres inlines it into the calling query; it
-- expands the address from the inet_send() wire bytes (4 header bytes, then
-- the address), so the netmask is ignored. Kept in sync with
-- serveradmin_extras/serveradmin_powerdns/migrations/0006_ptr_function.py.
create or replace function public.ptr(intern_ip inet) returns text
immutable strict language plpgsql as $$
declare
ip_part text;
ip_text text;
ip_arr text[];
ip_filled boolean;
begin
if family(intern_ip) = 4 then
return (
select string_agg(part, '.' order by ord desc) || '.in-addr.arpa'
from regexp_split_to_table(host(intern_ip), '\.') with ordinality as s(part, ord)
);
language sql immutable parallel safe as $$
select case family(intern_ip)
when 4 then
get_byte(inet_send(intern_ip), 7)::text || '.' ||
get_byte(inet_send(intern_ip), 6)::text || '.' ||
get_byte(inet_send(intern_ip), 5)::text || '.' ||
get_byte(inet_send(intern_ip), 4)::text || '.in-addr.arpa'
else
ip_text := '';
ip_arr := regexp_split_to_array(host(intern_ip), ':');
ip_filled = false;

foreach ip_part in array ip_arr loop
if length(ip_part) = 0 and not ip_filled then
ip_text := ip_text || repeat('0', 32 - (array_length(ip_arr, 1) - 1) * 4);
ip_filled = true;
else
ip_text := ip_text || lpad(ip_part, 4, '0');
end if;
end loop;

return (
select string_agg(part[1], '.' order by ord desc) || '.ip6.arpa'
from regexp_matches(ip_text, '.', 'g') with ordinality as s(part, ord)
);
end if;
end;
regexp_replace(reverse(encode(substring(inet_send(intern_ip) from 5), 'hex')), '(.)', '\1.', 'g')
|| 'ip6.arpa'
end
$$;

create index concurrently server_ptr_idx on public.server(public.ptr(intern_ip) text_pattern_ops);
Expand Down
Loading