From e15228a59ff2002b088ec8c91faafb18f009bb72 Mon Sep 17 00:00:00 2001 From: Auri <me@aurieh.me> Date: Sat, 22 Oct 2022 21:47:32 +0000 Subject: [PATCH] sql/v1tov2: properly handle directories in path_full_stem --- sql/v1tov2.sql | 50 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/sql/v1tov2.sql b/sql/v1tov2.sql index a7c4c6d..51f8733 100644 --- a/sql/v1tov2.sql +++ b/sql/v1tov2.sql @@ -44,28 +44,23 @@ CREATE FUNCTION path_normalize(object_path) RETURNS object_path LANGUAGE SQL AS $$SELECT regexp_replace($1, '/+', '/', 'g');$$; --- Given '/foo/bar.baz.qux', return '/foo/bar'. --- See bucket.enforce_unique_names and object.enforce_unique_name. -CREATE FUNCTION path_full_stem(object_path) RETURNS object_path - IMMUTABLE STRICT - LANGUAGE SQL - AS $$SELECT split_part(path_normalize($1), '.', 1);$$; - --- Given '/foo/bar/baz', return '/foo/bar'. --- Given '/', return '/'. --- Given 'foo', return ''. -CREATE FUNCTION path_directory(object_path) RETURNS object_path +-- Given '/foo/bar/baz', return ('/foo/bar', 'baz'). +-- Given 'foo', return ('', 'foo'). +CREATE FUNCTION path_split(object_path, OUT head object_path, OUT tail object_path) RETURNS record IMMUTABLE STRICT LANGUAGE plpgsql AS $$ DECLARE - l integer = length($1); + l integer := length($1); i integer; - head object_path = ''; BEGIN + head := ''; + tail := $1; + FOR i IN REVERSE l..1 LOOP IF starts_with(substr($1, i), '/') THEN head := substr($1, 0, i + 1); + tail := substr($1, i + 1); EXIT; END IF; END LOOP; @@ -73,8 +68,35 @@ CREATE FUNCTION path_directory(object_path) RETURNS object_path IF head != '' AND head != repeat('/', length(head)) THEN head := rtrim(head, '/'); END IF; + END + $$; - RETURN head; +-- Given '/foo/bar.baz.qux', return '/foo/bar'. +-- Given '/foo/bar.baz/qux.quux', return '/foo/bar.baz/qux'. +-- See bucket.enforce_unique_names and object.enforce_unique_name. +CREATE FUNCTION path_full_stem(object_path) RETURNS object_path + IMMUTABLE STRICT + LANGUAGE plpgsql + -- AS $$SELECT split_part(path_normalize($1), '.', 1);$$; + AS $$ + DECLARE + split record = path_split(path_normalize($1)); + BEGIN + RETURN split.head || '/' || split_part(split.tail, '.', 1); + END + $$; + +-- Given '/foo/bar/baz', return '/foo/bar'. +-- Given '/', return '/'. +-- Given 'foo', return ''. +CREATE FUNCTION path_directory(object_path) RETURNS object_path + IMMUTABLE STRICT + LANGUAGE plpgsql + AS $$ + DECLARE + split record = path_split($1); + BEGIN + RETURN split.head; END $$; -- GitLab