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).

Example 1
@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.

Example 2
@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).

Example 3
@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:

Example 4
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:

Example 5
@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.
Example
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:

Expected result
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.
Example
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

Expected result
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.