Leif Harald Karlsen
CREATE TABLE person(
pid int PRIMARY KEY,
firstname text,
lastname text,
bdate date
);
CREATE TABLE mother(
pid int REFERENCES person(pid),
mother int REFERENCES person(pid)
);
CREATE TABLE father(
pid int REFERENCES person(pid),
father int REFERENCES person(pid)
);
-- and so on...
CREATE VIEW parent (pid, parent) AS
SELECT pid, mother FROM mother
UNION ALL
SELECT pid, father FROM father;
CREATE VIEW grandmother(pid, grandmother) AS
SELECT p.pid, m.mother
FROM parent AS p JOIN mother AS m ON (p.parent = m.pid);
-- and so on...-- pid of grandmothers of 'Ole':
SELECT gm.mother
FROM person AS p
JOIN mother AS m USING (pid)
JOIN mother AS gm ON (m.mother = gm.pid)
WHERE p.firstname = 'Ole'
UNION ALL
SELECT gm.mother
FROM person AS p
JOIN father AS f JOIN mother;
JOIN mother AS gm ON (f.father = gm.pid)
WHERE p.firstname = 'Ole'
-- can be simplified to:
SELECT gm.grandmother
FROM person AS p
JOIN grandmother AS gm USING (pid=
WHERE p.firstname = 'Ole';
x has parent
y”?... UNION ALL VALUES (x, y))
$<identifier>$,
e.g. $body$)IF, FOR, variables, etc.BEGIN and ENDDELCARE for variablesRETURN-statementCREATE FUNCTION inc(n int) RETURNS int AS
$body$
SELECT n+1;
$body$ language SQL;
CREATE FUNCTION five() RETURNS int AS
$body$
SELECT 5;
$body$ language SQL;
SELECT inc(five()); --> 6
CREATE FUNCTION pick_person() RETURNS int AS
$body$
DECLARE
picked_person int;
BEGIN
picked_person = ( -- pick a person not already picked
SELECT pid FROM person
WHERE pid NOT IN (SELECT pid FROM picked)
LIMIT 1
);
INSERT INTO picked -- add person to picked
VALUES (picked_person);
RETURN picked_person; -- returned the picked person
END;
$body$ language PLPGSQL;INSERT,
UPDATE, DELETE)BEFORE, AFTER or
INSTEAD OF actionEACH ROW or
EACH STATEMENTTrigger functions are arbitrary functions that:
triggerNEW and
OLDNEW denotes the inserted/updated rowOLD is the row that is deleted (or before update)DELETE t WHERE c;UPDATE t SET deleted=true WHERE c;parent is a
table):INSERT, DELETE,
UPDATE, SELECT) to be executedDO ALSO) or instead of
(DO INSTEAD) an actionNEW and
OLDIF <condition> THEN <consequence>)IF mother(x, y) THEN parent(x, y)mother(x, y) -> parent(x, y)parent(x, y) <- mother(x, y)parent(x, y) :- mother(x, y)->
mother(x, y) -> parent(x, y)mother are also inserted into
parent<-
parent(x, y) <- mother(x, y)parents also queries for
mothersRELATION: Behaves as both VIEW (can be
defined) and TABLE (can INSERT INTO)IMPLICATION: Can use rules/implications to define
relationsIMPORT: Can import scripts
INSERT INTO a Lore-relation and use
other tables/views/relations to define it simultaneouslyRELATION in place of TABLEThe statement
gets translated into the following SQL:
CREATE TABLE person_stored (id int, pname text NOT NULL, UNIQUE (id, pname));
CREATE VIEW person_virtual AS
SELECT *
FROM person_stored
LIMIT 0;
CREATE VIEW person AS
SELECT *
FROM person_stored
UNION ALL
SELECT *
FROM person_virtual;
CREATE RULE person_insert_rule AS
ON INSERT TO person DO INSTEAD
INSERT INTO person_stored (SELECT NEW.id, NEW.name)
ON CONFLICT (id, pname) DO NOTHING; R becomes a VIEW
R that is the union of a table R_stored and a
view R_virtualINSERT INTO
R_storedVIEW
R_virtualT to a relation by just
CREATE RELATION FROM TABLE T(...);VIEWSCREATE RELATION person(id int, pname text NOT NULL);
CREATE RELATION student(id int, sname text NOT NULL);
CREATE RELATION employee(id int, ename text NOT NULL);
CREATE IMPLICATION person AS
SELECT * FROM student;
CREATE IMPLICATION person AS
SELECT * FROM employee;
INSERT INTO person VALUES (1, 'Ole');
INSERT INTO student VALUES (2, 'Per');
INSERT INTO employee VALUES (3, 'Kari');SELECT * FROM person;
gives:
-- id | pname
-- ----+-------
-- 1 | Ole
-- 2 | Per
-- 3 | Kari
-- (3 rows)
CREATE IMPLICATION creates parts of
VIEWsCREATE FORWARD IMPLICATION to
get forward-chaining implicationINSERTTRIGGERsCREATE FORWARD IMPLICATION person AS
SELECT * FROM student AS s;
CREATE FORWARD IMPLICATION person AS
SELECT * FROM employee AS e;
' || '
' || translation '
' || '
' \/ '
CREATE FUNCTION student_to_person_insert_trigger_fnc()
RETURNS trigger AS $body$
BEGIN
INSERT INTO person
SELECT * FROM (SELECT NEW.id, NEW.name) AS s;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
CREATE TRIGGER student_to_person_insert_trigger
AFTER INSERT ON student_stored
FOR EACH ROW
EXECUTE PROCEDURE student_to_person_insert_trigger_fnc();
INSERT INTO person
SELECT * FROM student AS s;
CREATE FUNCTION employee_to_person_insert_trigger_fnc()
RETURNS trigger AS $body$
BEGIN
INSERT INTO person
SELECT * FROM (SELECT NEW.id, NEW.name) AS e;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
CREATE TRIGGER employee_to_person_insert_trigger
AFTER INSERT ON employee_stored
FOR EACH ROW
EXECUTE PROCEDURE employee_to_person_insert_trigger_fnc();
INSERT INTO person
SELECT * FROM employee AS e;WITH.
E.g.:CREATE IMPLICATION ancestor AS
SELECT * FROM parent;
CREATE IMPLICATION ancestor AS
SELECT p.pid, a.ancestor
FROM parent AS p JOIN ancestor AS a ON (p.parent = a.pid);
' || '
' || translation '
' || '
' \/ '
CREATE VIEW ancestor_virtual (pid, ancestor) AS
WITH RECURSIVE
tmp_subquery(pid, ancestor) AS (
SELECT * FROM parent
UNION ALL
SELECT p.pid, a.ancestor_stored
FROM parent AS p -- Also include all explicit
JOIN ancestor_stored AS a ON (p.parent = a.pid) -- ancestors in recursion
UNION ALL
SELECT p.pid, a.tmp_subquery
FROM parent AS p
JOIN tmp_subquery AS a ON (p.parent = a.pid) -- Recursive call
)
SELECT * FROM tmp_subquery;DROP RELATION person; – deletes both views, the table
and all implications associated with personDROP RELATION TO TABLE person; – deletes views and
implications, renames person_stored to person,
keeps the data--clean flag to lore.jar to delete
all Lore-constructs
DROP RELATION TO TABLE <relation>; for
each relation--cleanAll flag to lore.jar to
delete everything
DROP RELATION <relation>; for each
relationCREATE RELATION introduces a relation which one can
both
INSERT INTO andIMPLICATIONsDROP RELATIONIMPLICATIONs can be either forward
(FORWARD) or backward-chaining (default)SELECT, one can do in
Lore implications!CREATE IMPICATION-syntaxperson(id, sname) <- student(id, sname); -- backward-chaining rule
person(x, y) <- employee(x, y);
mother(x, y) -> parent(x, y); -- forward-chaining rule
ancestor(x, y), ancestor(y, z) -> ancestor(x, z);
student(sid, sname), takes_course(sid, code, cname) : code >= 4000 AND code <= 6000 -> master_student(sid, sname);
ifi_student(sid, sname) <- student(sid, sname), takes_course(sid, code, cname) : cname LIKE 'IN%';
' || '
' || translation '
' || '
' \/ '
CREATE IMPLICATION person AS
SELECT id, sname FROM student AS t1(id, sname);
CREATE IMPLICATION person AS
SELECT x, y FROM employee AS t1(x, y);
CREATE FORWARD IMPLICATION parent AS
SELECT x, y FROM mother AS t1(x, y);
CREATE FORWARD IMPLICATION ancestor AS
SELECT x, z
FROM ancestor AS t1(x, y)
NATURAL JOIN ancestor AS t2(y, z);
CREATE FORWARD IMPLICATION master_student AS
SELECT sid, sname
FROM student AS t1(sid, sname)
NATURAL JOIN takes_course AS t2(sid, code, cname)
WHERE code >= 4000 AND code <= 6000;
CREATE IMPLICATION ifi_student AS
SELECT sid, sname
FROM student AS t1(sid, sname)
NATURAL JOIN takes_course AS t2(sid, code, cname)
WHERE cname LIKE 'IN%';INSERT INTOimports in programming languagesIMPORT and the a string with
the URL to the fileIMPORT-statement is replaced with the Lore-commands
in the referenced filelore for meta-datalore.relations: list of all defined relationslore.backward_implications: list of all backward
implicationslore.forward_implications: list of all forward
implicationsDROP RELATION-statements: Delete implications
associated with relation--clean and --cleanAll flags: Delete all
relationsCREATE IMPLICATION-statements: Extend view
definition--help for info and optionsscript.lore into a database, simply
executejava -jar lore.jar <flags> script.lore
java -jar lore.jar -h dbpg-ifi-kurs03 -U in5800_leifhka_user -d in5800_leifhka -P pwd123 script.lore
--debug flag.-L flagFROM person AS p)VIEWs and
TRIGGERs for defining terms, abstractions, etc.Person) is still tightly coupled to its
attributes/propertiesEmployees are
Persons without also stating how Employee’s
attributes relates to Person’s attributes