The Coolest Language-Integrated Query Feature in Ballerina, “Query Expression”!!

Lasini Liyanage
4 min readAug 13, 2020

--

Ballerina is an open-source programming language developed by WSO2 which allows programmers to do DevOps and Agile-Oriented development quite easily. It is unique from many other existing programming languages because of its,

  • support in networking, existent in the language syntax itself
  • visual representation of the program logic as sequence diagrams
  • ease in moving from code to cloud, and many more.

To find out more about Ballerina, check out the Ballerina website here.

Among many other new features, Query Expression is one of the coolest features 😉 introduced with Ballerina 1.2.0. It provides a way to perform query functionality using SQL-like syntax.

A query expression is similar to a list comprehension and consists of a sequence of clauses. from, let, where, select, and limit are some of the available query clauses. If the execution of a query clause is completed early with an error value, the result of the query is this error value. Otherwise, the result of the query expression is either a list , stream , table , string or an xml constructed from the sequence of values emitted by the last clause.

The following is a use-case of a query expression. (I’m trying out these examples with the latest Ballerina Swan Lake preview version, swan-lake-preview2)

https://gist.github.com/lasinicl/27a69ca10e397675b71904329b9474d5

The from clause works similar to a foreach statement. It iterates the customerList . The let clause binds variables. The where clause applies a boolean condition on each element in the customerList and filters the ones for which the specified condition is true. If the condition evaluates to false, the subsequent clauses are omitted for that iteration. The select clause emits the output values. It is evaluated for each iteration. The number of output items is limited by the limit clause. The result of this query expression is a list of Customers.

A boolean value true is assigned to variableloyalty using the let clause. The where clause ensures that only customers with noOfItems > 15 are filtered from the customerList. The customerId, name, noOfItems values of each customer in the customerList is assigned to customerId, name, noOfItems fields and value of loyalty is assigned to isLoyalMember field of each Customer emitted from the select clause. In the above example, customers with customerId 2 , 3 , and5 satisfy the given condition. But the limit clause will limit the number of items to two. Therefore the output of the above query expression will be the following.

customerId=2 name=Tobi noOfItems=20 isLoyalMember=true
customerId=3 name=Frank noOfItems=30 isLoyalMember=true

Stream from the query expression

To construct a bounded stream from the query expression you simply need to add the stream keyword with the from clause.

https://gist.github.com/lasinicl/caa015850ad45d6613a3391de027c85d

The output stream from the above query expression will contain the same values as the list output.

customerId=2 name=Tobi noOfItems=20 isLoyalMember=true
customerId=3 name=Frank noOfItems=30 isLoyalMember=true

Table from the query expression

Adding the table keyword with a key specifier as a prefix for the from clause constructs a table from query expression.

https://gist.github.com/lasinicl/e9769087868e9a8bd2593165594f606a

A CustomerTable table type with Customer members uniquely identified by their customerId and name is created to capture the output from the query expression. The outputTable will contain the following members.

customerId=2 name=Tobi noOfItems=20 isLoyalMember=true
customerId=3 name=Frank noOfItems=30 isLoyalMember=true

With keyed tables, key conflicts can occur when select emits a row that has the same key as a row that it emitted earlier. Then a key conflict error will be output from the query expression. In order to customize this key conflict error, you can include an on conflict clause specifying the error that you want to have for a key conflict.

https://gist.github.com/lasinicl/77dcbe235456d442ac67a6482f067c79

It is required that the keyConflictErr expression belongs to error type. In the above example Customer c3 is repeated in the customerList. Therefore a key conflict will occur when select tries to emit a customer with the same keys twice, since the keyed table constructed from the query expression can not consist of two members with the same (customerId, name).

Then the result of the query expression;outputTable will be the following when a key conflict is present.

error Key conflict in query

String from the query expression

When a string is constructed from the query expression, it concatenates the string type values emitted from the select clause to form the output string.

String from query expression

The output from the above query expression will be,

Tobi 20,Frank 30,

XML from the query expression

Similar to string , the XML type values emitted from the select clause is concatenated to form the XML output from query expression.

https://gist.github.com/lasinicl/801ebe666aed8b40ce84fa49a8ad16c3

The output from the above query expression will be,

<name>Melina</name><name>Tobi</name>

That’s it! Hope you got an understanding about Query Expression in Ballerina. 😄 There are a lot more cool stuff that can be done using query expression . Let’s try them out in the upcoming articles. 😃

Adiós!!

References
https://ballerina.io/
https://ballerina.io/spec/lang/draft/v2020-06-18/

--

--

Lasini Liyanage
Lasini Liyanage

No responses yet