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.