blob: 863316b82d9b3872865b3b29dd38939bb6115924 (
plain) (
tree)
|
|
(** Relation: a lightweight versioned root describing a named collection of
tuples. Physical storage owns the tuple B+ tree; this object holds only
metadata and a tree pointer.
Class hierarchy:
- [relation] — base, storable, has membership_criteria/provenance/lineage
- [ephemeral_relation] — adds a generator (query-time computed, not stored)
- [pseudo_relation] — adds a producer (system-defined, not stored)
- [domain] — adds a generator (system or user defined, not necessarily
stored) *)
module RelationConstraint = struct
type name = string
type t = (name * Constraint.t) list
end
module Lineage = struct
(** Tracks which relational algebra operations produced the tuples. Lives in
the relation, but refers to the tuple. *)
type t =
| Base of Conventions.Name.t
| Select of t
| Project of Conventions.Name.t list * t
| Join of t * t
| ThetaJoin of t * t
| Sort of t
| Take of t
end
module Provenance = struct
(** Tracks which base relation each attribute originates from. Lives on the
relation and refers to the `entity group`. *)
type source = {relation: Conventions.Name.t; attribute: string}
type t =
| Undefined
| Base of Conventions.Name.t
| Sources of source list BatMap.String.t
(** Maps attribute name -> list of sources (multiple after joins) *)
let base ~relation ~attributes : t =
Sources
(List.fold_left
(fun acc attr -> BatMap.String.add attr [{relation; attribute= attr}] acc)
BatMap.String.empty attributes )
let empty : t = Sources BatMap.String.empty
let undefined : t = Undefined
end
type producer = (string * Conventions.AbstractValue.t) list -> Generator.t
type kind = [`Stored | `Ephemeral | `Pseudo | `Domain]
class virtual relation =
object (_self)
method virtual kind : kind
method virtual name : Conventions.Name.t
method virtual schema : Schema.t
method virtual hash : Conventions.Hash.t
method virtual constraints : RelationConstraint.t option
method virtual cardinality : Conventions.Cardinality.t
method virtual lineage : Lineage.t
method virtual provenance : Provenance.t
method virtual membership_criteria : Tuple.t -> bool
method virtual timestamp : float
method virtual serialize : unit -> Storable.Relation.t
end
class stored ~name:(init_name : Conventions.Name.t) ~schema:(init_schema : Schema.t)
~constraints:(init_constraints : RelationConstraint.t option)
~cardinality:(init_cardinality : Conventions.Cardinality.t)
~membership_criteria:(init_membership : Tuple.t -> bool)
~lineage:(init_lineage : Lineage.t option) ~provenance:(init_provenance : Provenance.t option) =
object
inherit relation
val name = init_name
val schema = init_schema
val tree_pointer : Conventions.Hash.t option = None
val constraints = init_constraints
val cardinality = init_cardinality
val membership_criteria = init_membership
val timestamp = Unix.gettimeofday ()
val lineage = Option.value init_lineage ~default:(Lineage.Base init_name)
val provenance =
Option.value init_provenance
~default:(Provenance.base ~relation:init_name ~attributes:(Schema.attributes init_schema))
method name = name
method kind = `Stored
method hash = Option.value tree_pointer ~default:""
method schema = schema
method tree_pointer = tree_pointer
method constraints = constraints
method cardinality = cardinality
method membership_criteria = membership_criteria
method timestamp = timestamp
method lineage = lineage
method provenance = provenance
method set_tree_pointer tp = {<tree_pointer = tp; timestamp = Unix.gettimeofday ()>}
method set_cardinality c = {<cardinality = c>}
method set_constraints c = {<constraints = c>}
method serialize () =
{Storable.Relation.name; schema; tree_pointer= Option.value tree_pointer ~default:""}
end
class ephemeral ~name:(init_name : Conventions.Name.t) ~schema ~constraints ~cardinality
~membership_criteria ~lineage ~provenance ~generator:(init_generator : Generator.t) =
object
inherit relation
val name : Conventions.Name.t = init_name
val schema : Schema.t = schema
val generator : Generator.t = init_generator
val constraints = constraints
val cardinality = cardinality
val membership_criteria = membership_criteria
val lineage = Option.value lineage ~default:(Lineage.Base init_name)
val provenance = Option.value provenance ~default:(Provenance.Base init_name)
val timestamp = Unix.gettimeofday ()
method name = name
method kind = `Ephemeral
method schema = schema
method generator = generator
method hash = Conventions.Hash.hash_text (name ^ "ephemeral")
method constraints = constraints
method cardinality = cardinality
method membership_criteria = membership_criteria
method lineage = lineage
method provenance = provenance
method timestamp = timestamp
method serialize () = failwith "Ephemeral relations cannot be serialized directly"
end
class pseudo ~name:(init_name : Conventions.Name.t) ~schema ~constraints ~cardinality
~membership_criteria ~lineage ~provenance ~producer:(init_producer : producer) =
object
inherit relation
val name = init_name
val schema = schema
val producer = init_producer
val constraints = constraints
val cardinality = cardinality
val membership_criteria = membership_criteria
val lineage = Option.value lineage ~default:(Lineage.Base init_name)
val provenance = provenance
val timestamp = Unix.gettimeofday ()
method name = name
method kind = `Pseudo
method schema = schema
method producer = producer
method as_generator (bindings : (string * Conventions.AbstractValue.t) list) : Generator.t =
producer bindings
method hash = Conventions.Hash.hash_text (name ^ "pseudo")
method constraints = constraints
method cardinality = cardinality
method membership_criteria = membership_criteria
method lineage = lineage
method provenance = provenance
method timestamp = timestamp
(* TODO: Remove this from the virtual definition *)
method serialize () = failwith "Pseudo relations are procedural"
end
let deserialize_stored (_bytes : bytes) : (stored, string) result =
try
let stored = Storable.Relation.of_bytes _bytes in
let membership_criteria =
Constraint.build_membership_criteria ~_name:stored.name ~schema:stored.schema
in
Ok
(new stored
~name:stored.name ~schema:stored.schema ~constraints:None
~cardinality:Conventions.Cardinality.ConstrainedFinite ~membership_criteria ~lineage:None
~provenance:None )
with Invalid_argument message -> Error message
class domain ~name ~schema ~constraints ~cardinality ~membership_criteria ~lineage ~provenance
~generator =
object
inherit
ephemeral
~name ~schema ~constraints ~cardinality ~membership_criteria ~lineage ~provenance ~generator
method! kind = `Domain
end
|