62 lines
2.9 KiB
PL/PgSQL
62 lines
2.9 KiB
PL/PgSQL
CREATE OR REPLACE FUNCTION project_select(relname text, mapname text, compname text, worldname text, newrelname text, newmapname text, newcompname text, newworldname text, attributes _text, "left" _text, op _text, "right" _text)
|
|
RETURNS void AS
|
|
$BODY$ DECLARE cols text;
|
|
colsQuoted text;
|
|
cond1 text; -- the condition used to filter the template relation; form: (A1 op1 c1 OR A1 IS NULL) AND (A2 op2 c2 OR A2 IS NULL) AND ...
|
|
cond3 text; -- the condition used for filtering the component relation; form: WHEN 'A1' THEN Value op1 c1 WHEN 'A2' THEN Value op2 c2 ...
|
|
cond4 text; -- the condition used to filter the mapping relation; form: Col NOT IN ('A', 'B', ...)
|
|
size integer;
|
|
BEGIN
|
|
cond1 = '';
|
|
cond3 = '';
|
|
|
|
IF array_upper(attributes, 1) = 1 AND attributes[1] = '*' THEN
|
|
cols = '*';
|
|
cond4 = 'false';
|
|
ELSE
|
|
cols = 'TID, ' || array_to_string(attributes, ',');
|
|
colsQuoted = '''' || array_to_string(attributes, ''',''') || '''';
|
|
cond4 = 'Col NOT IN (' || colsQuoted || ') ';
|
|
END IF;
|
|
size = array_upper(left, 1);
|
|
FOR i IN 1..size LOOP
|
|
IF i > 1 THEN
|
|
cond1 = cond1 || ' AND (' || left[i] || ' ' || op[i] || ' ' || right[i] || ' OR ' || left[i] || ' = -1)';
|
|
ELSE
|
|
cond1 = '(' || left[i] || ' ' || op[i] || ' ' || right[i] || ' OR ' || left[i] || ' = -1)';
|
|
END IF;
|
|
cond3 = cond3 || ' WHEN ' || quote_literal(left[i]) || ' THEN Value ' || op[i] || ' ' || right[i];
|
|
END LOOP;
|
|
EXECUTE '
|
|
CREATE TABLE ' || newRelName || ' AS
|
|
SELECT ' || cols || ' FROM ' || relName || ' WHERE ' || cond1 || ';';
|
|
EXECUTE '
|
|
CREATE TABLE ' || newMapName || ' AS SELECT * FROM ' || mapName || ' WHERE Relation = ' || quote_literal(relName)
|
|
|| ' AND TID IN (SELECT TID FROM ' || newRelName || ');';
|
|
EXECUTE '
|
|
CREATE TABLE ' || newCompName || ' AS
|
|
SELECT ' || compName || '.* FROM ' || compName || ', ' || newMapName || '
|
|
WHERE ' || compName || '.HID = ' || newMapName || '.HID AND
|
|
(CASE Col ' || cond3 || ' ELSE true END);';
|
|
EXECUTE '
|
|
CREATE TABLE DEL WITHOUT OIDS AS
|
|
SELECT TID FROM ' || newMapName || '
|
|
WHERE HID NOT IN (SELECT HID FROM ' || newCompName || ');';
|
|
EXECUTE '
|
|
DELETE FROM ' || newRelName || '
|
|
WHERE TID IN (SELECT DEL.TID FROM DEL);
|
|
DELETE FROM ' || newMapName || '
|
|
WHERE ' || cond4 || ' OR TID IN (SELECT DEL.TID FROM DEL);';
|
|
EXECUTE '
|
|
DELETE FROM ' || newCompName || '
|
|
WHERE HID NOT IN (SELECT HID FROM ' || newMapName || ');';
|
|
DROP TABLE DEL;
|
|
--EXECUTE '
|
|
-- CREATE TABLE ' || newWorldName || ' AS SELECT DISTINCT ' || worldName || '.* FROM ' || worldName || ', ' || newCompName ||
|
|
-- ' WHERE ' || worldName || '.cid = ' || newCompName || '.cid AND ' || worldName || '.wid = ' || newCompName || '.wid;';
|
|
RETURN;
|
|
END;
|
|
$BODY$
|
|
LANGUAGE 'plpgsql' VOLATILE;
|
|
|