forked from dCache/dcache
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chimera: fix handling of bytea data in path2inode and path2inodes st…
…ored procedures when migrating from 8.4 to 9.2 postgresql it was noticed that assigning of bytea data to varchar produced unexpected result due to bytea_output='hex' as default in postgresql 9.2 This patch addresses it by calling encode(ifiledata,'escape') before assigning it to varchar variables Ticket: #number Acked-by: Paul Millar, Tigra Mkrtchyan Target: trunk Request: 2.2 Request: 2.6 Request: 2.7 Require-book: no Require-notes: no (cherry picked from commit b995602)
- Loading branch information
1 parent
7af4189
commit 1026c38
Showing
2 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
modules/chimera/src/main/resources/org/dcache/chimera/changelog/changeset-2.9.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
<databaseChangeLog | ||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog | ||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> | ||
|
||
<changeSet author="litvinse" id="18" dbms="postgresql"> | ||
<comment>use encode on bytea field</comment> | ||
<createProcedure> | ||
CREATE OR REPLACE FUNCTION | ||
path2inode(root varchar, path varchar) | ||
RETURNS varchar AS $$ | ||
DECLARE | ||
id varchar := root; | ||
elements varchar[] := string_to_array(path, '/'); | ||
child varchar; | ||
itype INT; | ||
link varchar; | ||
BEGIN | ||
FOR i IN 1..array_upper(elements,1) LOOP | ||
SELECT dir.ipnfsid, inode.itype INTO child, itype FROM t_dirs dir, t_inodes inode WHERE dir.ipnfsid = inode.ipnfsid AND dir.iparent=id AND dir.iname=elements[i]; | ||
IF itype=40960 THEN | ||
SELECT encode(ifiledata,'escape') INTO link FROM t_inodes_data WHERE ipnfsid=child; | ||
IF link LIKE '/%' THEN | ||
child := path2inode('000000000000000000000000000000000000', | ||
substring(link from 2)); | ||
ELSE | ||
child := path2inode(id, link); | ||
END IF; | ||
END IF; | ||
IF child IS NULL THEN | ||
RETURN NULL; | ||
END IF; | ||
id := child; | ||
END LOOP; | ||
RETURN id; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
</createProcedure> | ||
<createProcedure> | ||
CREATE OR REPLACE FUNCTION | ||
path2inodes(root varchar, path varchar, OUT inode t_inodes) | ||
RETURNS SETOF t_inodes AS $$ | ||
DECLARE | ||
dir varchar; | ||
elements text[] := string_to_array(path, '/'); | ||
inodes t_inodes[]; | ||
link varchar; | ||
BEGIN | ||
-- Find the inode of the root | ||
SELECT * INTO inode FROM t_inodes WHERE ipnfsid = root; | ||
IF NOT FOUND THEN | ||
RETURN; | ||
END IF; | ||
|
||
-- We build an array of the inodes for the path | ||
inodes := ARRAY[inode]; | ||
|
||
-- For each path element | ||
FOR i IN 1..array_upper(elements,1) LOOP | ||
-- Return empty set if not a directory | ||
IF inode.itype != 16384 THEN | ||
RETURN; | ||
END IF; | ||
|
||
-- The PNFS ID of the directory | ||
dir := inode.ipnfsid; | ||
|
||
-- Lookup the next path element | ||
SELECT t_inodes.* INTO inode | ||
FROM t_inodes, t_dirs | ||
WHERE t_inodes.ipnfsid = t_dirs.ipnfsid | ||
AND t_dirs.iparent = dir AND iname = elements[i]; | ||
|
||
-- Return the empty set if not found | ||
IF NOT FOUND THEN | ||
RETURN; | ||
END IF; | ||
|
||
-- Append the inode to the result set | ||
inodes := array_append(inodes, inode); | ||
|
||
-- If inode is a symbolic link | ||
IF inode.itype = 40960 THEN | ||
-- Read the link | ||
SELECT encode(ifiledata,'escape') INTO STRICT link | ||
FROM t_inodes_data WHERE ipnfsid = inode.ipnfsid; | ||
|
||
-- If absolute path then resolve from the file system root | ||
IF link LIKE '/%' THEN | ||
dir := '000000000000000000000000000000000000'; | ||
link := substring(link from 2); | ||
|
||
-- Call recursively and add inodes to result set | ||
FOR inode IN SELECT * FROM path2inodes(dir, link) LOOP | ||
inodes := array_append(inodes, inode); | ||
END LOOP; | ||
ELSE | ||
-- Call recursively and add inodes to result set; skip | ||
-- first inode as it is the inode of dir | ||
FOR inode IN SELECT * FROM path2inodes(dir, link) OFFSET 1 LOOP | ||
inodes := array_append(inodes, inode); | ||
END LOOP; | ||
END IF; | ||
|
||
-- Return empty set if link could not be resolved | ||
IF NOT FOUND THEN | ||
RETURN; | ||
END IF; | ||
|
||
-- Continue from the inode pointed to by the link | ||
inode = inodes[array_upper(inodes,1)]; | ||
END IF; | ||
END LOOP; | ||
|
||
-- Output all inodes | ||
FOR i IN 1..array_upper(inodes,1) LOOP | ||
inode := inodes[i]; | ||
RETURN NEXT; | ||
END LOOP; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
</createProcedure> | ||
|
||
</changeSet> | ||
</databaseChangeLog> |