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 END
DELCARE
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 STATEMENT
Trigger functions are arbitrary functions that:
trigger
NEW
and
OLD
NEW
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
OLD
IF <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)
parent
s also queries for
mother
sRELATION
: Behaves as both VIEW
(can be
defined) and TABLE
(can INSERT INTO
)IMPLICATION
: Can use rules/implications to define
relationsIMPORT
: Can import scriptsINSERT INTO
a Lore-relation and use
other tables/views/relations to define it simultaneouslyRELATION
in place of TABLE
The 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_virtual
INSERT INTO
R_stored
VIEW
R_virtual
T
to a relation by just
CREATE RELATION FROM TABLE T(...);
VIEWS
CREATE 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
VIEW
sCREATE FORWARD IMPLICATION
to
get forward-chaining implicationINSERT
TRIGGER
sCREATE 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 person
DROP 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
andIMPLICATION
sDROP RELATION
IMPLICATION
s 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 INTO
import
s 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
)VIEW
s and
TRIGGER
s for defining terms, abstractions, etc.Person
) is still tightly coupled to its
attributes/propertiesEmployee
s are
Person
s without also stating how Employee
’s
attributes relates to Person
’s attributes