Bindings
Examples for this documentation page are not currently checked automatically. |
These annotations (@bind
, @mapping
, @qbind
) allow to customize the data sources for the @input
annotation or the targets for the @output
annotation.
@bind
@bind
binds an input or output atom to a source.
The syntax for @bind
is the follows:
@bind("atomName","data source","outermost container","innermost container").
where atomName
is the atom we want to bind, data source
is the name of a source defined in the Vadalog configuration, outermost container
is a container in the data source (e.g., a schema in a relational database), innermost container
is a content in the data source (e.g. a table in a relational database).
@input("m").
@input("q").
@output("m").
@bind("m","postgres","doctors_source","Medprescriptions").
@bind("q","sqlite","doctors_source","Medprescriptions").
m(X) :- b(X),q(X).
This example reads the facts for m
from a Postgres data source, specifically from
schema doctors_source
and table Metprescriptions
, reads facts for q
from a SQLite (in SQLite the schema is ignored)
data source and performs a join.
Bind multiple sources to an input predicate
You can bind multiple external sources (csv, postgres, sqlite, neo4j, …) to a single input predicate. In this example we have a graph partitioned in a csv file and a postgres database and we bind them to the predicate edge
. As a result the facts from the two sources are merged into edge
.
@input("edge").
@output("path").
path(X,Y) :- edge(X,Y).
path(X,Z) :- edge(X,Y),path(Y,Z).
@bind("edge","csv","path/to/myCsv1/","graph_partition_1.csv").
@bind("edge","postgres","graph_source_db","graph_partition_2_table").
@output("path").
@mapping
@mapping
maps specific columns of the input/output source to a position of an atom.
An atom that appears in a @mapping
annotation must also appear in a @bind
annotation.
The syntax is the following:
@mapping("atomName",positionInAtom,"columnName","columnType").
where atomName
is the atom we want to map, positionInAtom
is an integer (from 0)
denoting the position of the atom that we want to map; columnName
is the name of the column in the source (or equivalent data structure), columnType
is an indication of the type in the source. The following types can be specified: string, int, double, boolean and date.
@input("m").
@bind("m","postgres","doctors_source","Medprescriptions").
@mapping("m",0,"id","int").
@mapping("m",1,"patient","string").
@mapping("m",2,"npi","int").
@mapping("m",3,"doctor","string").
@mapping("m",4,"spec","string").
@mapping("m",5,"conf","int").
In this example, we map the columns of the Medprescriptions
table.
Observe that mappings can be omitted for both @input
and @output
atoms. In such case they are automatically inferred from the source (target); the result can be however unsatisfactory depending on the sources, since some of them do not support positional reference to the attributes.
Positions are 0-based. |
@qbind
@qbind
binds an input atom to a source, generating the facts for the atom as the result of a query executed on the source.
The syntax is the following:
@qbind("atomName","data source","outermost container","query").
where atomName
is the atom we want to bind, data source
is the name of a source defined in the Vadalog configuration, outermost container
is a container in the data source (e.g., a schema in a relational database), query
is a query in the language supported by the source (e.g., SQL for relational databases).
@qbind("t","postgres","vada","select * from ""TestTable"" where id between 1 and 2").
Here we bind atom t
to the data source postgres, selecting a specific content from the table TestTable
.
You can also use parametric @qbind
, for example:
qbind("t","postgres","vada","select * from ""TestTable"" where id = $\{1}").
where ${1}
is a parameter, which will have the values of the first input field t
.
Parametric @qbind
should be used in joins with other atoms.
You can also use multiple parameters within a parametric @qbind
:
@qbind("t","postgres","vada","select * from ""TestTable"" where id = $\{1} and field = $\{2}").
where ${1}
and ${2}
are the first and second parameters of all t
results.
@delete
@delete
annotation specifies what data should be removed from a datasource.
The syntax is the following:
@delete("atomName","set of key positions").
The delete annotation must be accompanied with a @bind
annotation that binds "atomName"
with a data source.
Positions are 0-based. |
q("a", "b").
q("c", "d").
p(X, Y) :- q(X, Y).
@bind("p", "postgres", "schema_test", "test_table").
@delete("p", {0}).
Suppose the "test_table"
contains facts test_table(a, 1), test_table(a,2), test_table(d, 1)
.
The result of executing the program is:
test_table(d, 1)
Indeed, p
contains facts with "a"
and "c"
on the key position(s) defined in the delete annotation, and thus rows with these values on the key positions are deleted from test_table
.
@update
The @update
annotation is similar to @delete
. It specifies how a data source is updated.
The syntax is the following:
@update("atomName","set of key positions").
The update annotation must be accompanied with a @bind
annotation that binds "atomName"
with a data source.
The result of this command is an update in the datasource that is bind with "atomName"
.
Positions are 0-based. |
q("a", "b").
q("c", "d").
p(X,Y) :- q(X,Y).
@bind("p", "postgres", "schema_test", "test_table").
@update("p", {0}).
Suppose the "test_table"
contains facts test_table(a, b), test_table(a,2), test_table(c, e)
.
The result of executing the program is the facts
test_table(a, b), text_table(a, b) and test_table(c,d)
Indeed, p contains facts with "a" and "c" on the key position(s) from the @update
, and thus rows with these values on the key positions are updated with the inferred data. Note that updates can result in duplicates in the data source.