42
Tree Tricks OSDC Melbourne 2010/11/24 Copyright(C) 2010 by David Fetter All Rights Reserved. Tuesday, November 23, 2010

Tree tricks osdc_melbourne_20101124

Embed Size (px)

Citation preview

Tree TricksOSDC Melbourne 2010/11/24Copyright(C) 2010 by David Fetter

All Rights Reserved.

Tuesday, November 23, 2010

What’s a Tree, Really?

Plant

Perennial

Woody

Secondary branches

Off ground

Apical Dominance

Tuesday, November 23, 2010

Tuesday, November 23, 2010

What’s a Tree, Really?

Graph

Directed

Connected

Acyclic

Max(indegree) = 1

Tuesday, November 23, 2010

What’s a Graph, Really?

Tuesday, November 23, 2010

What’s a Graph, Really?

Nodes

Tuesday, November 23, 2010

What’s a Graph, Really?

NodesEdges

Tuesday, November 23, 2010

Representing Graphs

CREATE TABLE message ( message_id SERIAL PRIMARY KEY, parent_message_id INTEGER REFERENCES message, sender email NOT NULL, list TEXT NOT NULL, ...);

Tuesday, November 23, 2010

FAIL!Tuesday, November 23, 2010

Separate Your Concerns.

Tuesday, November 23, 2010

Representing GraphsCREATE TABLE message ( message_id SERIAL PRIMARY KEY, sender email NOT NULL, list TEXT NOT NULL, ...);

CREATE TABLE edge ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message, PRIMARY KEY(tail, head));

Tuesday, November 23, 2010

WIN!Tuesday, November 23, 2010

Mathematical Flashback

Tuesday, November 23, 2010

Binary Relations

Tuesday, November 23, 2010

Binary Relations

Reflexive

Tuesday, November 23, 2010

Binary Relations

Reflexive

Symmetric

Tuesday, November 23, 2010

Binary Relations

Reflexive

Symmetric

Transitive

Tuesday, November 23, 2010

CLOSURE(need to get some)

Tuesday, November 23, 2010

Reflexive ClosureCREATE TABLE reflexive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO reflexive_closureSELECT tail, head FROM edge UNIONSELECT tail, tail FROM edge UNIONSELECT head, head FROM edge;

Tuesday, November 23, 2010

Symmetric Closure

CREATE TABLE symmetric_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO symmetric_closureSELECT tail, head FROM edge UNIONSELECT head, tail FROM edge;

Tuesday, November 23, 2010

Transitive ClosureCREATE TABLE transitive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

Tuesday, November 23, 2010

Transitive ClosureCREATE TABLE transitive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO transitive_closure

Tuesday, November 23, 2010

Transitive ClosureCREATE TABLE transitive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO transitive_closureSELECT

Tuesday, November 23, 2010

Transitive ClosureCREATE TABLE transitive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO transitive_closureSELECTEr

Tuesday, November 23, 2010

Transitive ClosureCREATE TABLE transitive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO transitive_closureSELECTErUm

Tuesday, November 23, 2010

Transitive ClosureCREATE TABLE transitive_closure ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message);

INSERT INTO transitive_closureSELECTErUmHrm...

Tuesday, November 23, 2010

Down the Rabbit Hole

Tuesday, November 23, 2010

Transitive Closure QueryWITH RECURSIVE t(tail, head, chain) AS ( SELECT tail, head, ARRAY[tail, head] FROM edgeUNION ALL SELECT e.tail, e.head, t.chain || e.head FROM edge e JOIN t ON (e.tail = t.head) WHERE e.tail <> ANY(t.chain))SELECT tail, head FROM t

Tuesday, November 23, 2010

Forest Constraints

?Tuesday, November 23, 2010

What’s a Tree, Really?

Graph

Directed

Connected

Acyclic

Max(indegree) = 1

Tuesday, November 23, 2010

Max(indegree) = 1

CREATE TABLE edge ( tail INTEGER NOT NULL REFERENCES message, head INTEGER NOT NULL REFERENCES message, PRIMARY KEY(tail, head));

ALTER TABLE edge ADD UNIQUE(head)

Tuesday, November 23, 2010

No Cycles!

Tuesday, November 23, 2010

Cycle FinderWITH RECURSIVE t(tail, head, chain) AS ( SELECT tail, head, ARRAY[tail, head] FROM edgeUNION ALL SELECT e.tail, e.head, t.chain || e.head FROM edge e JOIN t ON (t.head = e.tail) WHERE e.tail = ANY(t.chain))SELECT * FROM t

Tuesday, November 23, 2010

Cycle Finder FunctionCREATE OR REPLACE FUNCTION has_cycle()RETURNS BOOLEANLANGUAGE SQL AS $$SELECT EXISTS ( WITH RECURSIVE t(tail, head, chain) AS ( SELECT tail, head, ARRAY[tail, head] FROM edge UNION ALL SELECT e.tail, e.head, t.chain || e.head FROM edge e JOIN t ON (t.head = e.tail) WHERE e.tail = ANY(t.chain) ) SELECT * FROM t)

Tuesday, November 23, 2010

Cyclotomic Trigger FunctionCREATE OR REPLACE FUNCTION decyclifier()RETURNS TRIGGERLANGUAGE plpgsqlAS $$BEGIN IF (has_cycle()) THEN RAISE ERROR 'No cycles allowed!'; END IF; RETURN NEW;END;

Tuesday, November 23, 2010

Cyclotomic Trigger

CREATE TRIGGER edge_decyclifier AFTER INSERT OR UPDATE ON edge FOR EACH STATEMENT EXECUTE PROCEDURE decyclifier();

Tuesday, November 23, 2010

Tree Constraint

Forest Constraint +Unique Non-head Node

Tuesday, November 23, 2010

Tree ConstraintCREATE OR REPLACE FUNCTION count_only_heads()RETURNS INTEGERLANGUAGE SQLAS $$SELECT count(tail)FROM edge eWHERE NOT EXISTS ( SELECT 1 FROM edge WHERE edge.head = e.tail)$$;

Tuesday, November 23, 2010

Tree ConstraintCREATE OR REPLACE FUNCTION one_head()RETURNS TRIGGERLANGUAGE plpgsqlAS $$BEGIN IF count_only_heads() <> 1 THEN RAISE EXCEPTION 'This is a tree!'; END IF; RETURN NEW;END;$$;

Tuesday, November 23, 2010

Tree Constraint

CREATE TRIGGER edge_one_head AFTER INSERT OR UPDATE OR DELETE ON edge EXECUTE PROCEDURE one_head();

Tuesday, November 23, 2010

Questions?Comments?Brickbats?

Tuesday, November 23, 2010

Thanks!Copyright(C) 2010 by David Fetter

All Rights Reserved.

Tuesday, November 23, 2010