Luminesce SQL queries are written in the SQL dialect of SQLite, with the syntactical extensions and limitations described below. See which tools are available to write queries.
Note a query can be written either for a data provider or a direct provider, and there are some syntactical differences between them. In particular, direct providers have an arbitrary syntax that may differ for each.
Summary
Luminesce SQL supports most of the syntax of the SQLite SELECT statement. It does not support data definition language (DDL) syntax for creating or modifying database objects.
Common table expressions (CTE) are not supported in Luminesce
SELECT
statements but a re-usable variable syntax is available instead.TYPES
statements can be used before LuminesceSELECT
statements to force type conversion on columns.FOR-EACH
loops can be emulated using APPLY statements.Most types of JOIN clause are supported.
A
WAIT
modifier is available to pause query execution.A number of common SQL functions are supported, and we've supplemented these with sets of custom functions and statistical functions.
A number of PRAGMA statements specific to Luminesce are supported.
A number of ways to convert to and from JSON are supported.
Parameterised queries can be run using
:<unique-name>:<default-value>
.Dates must be encapsulated in
#
rather than'
characters, so for example#2023-11-15 15:59:59#
(though other date formats can also be understood).Strings must be encapsulated in
'
rather than"
characters, so for examplePortfolioScope = 'Finbourne-Examples'
. Note SQLite interprets a column name encapsulated in"
characters as a string literal if it doesn't match a valid column name. For this reason, we recommend encapsulating column names in[]
characters. Read more on this in the SQLite documentation.Multiple lines can be commented out using
/*
and*/
characters at the beginning and end respectively.
See the full list of valid keywords (both inherited from SQLite and proprietary to FINBOURNE).
SELECT statement examples | Explanation |
| Selects all the columns from |
| Selects the X and Y columns |
| Selects all the columns except X and Y. Can use the |
| Selects the main columns (those considered most important by the provider author) |
| Selects the main columns except X and Y |
| Returns only the first 5 records |
For a Some.Provider
that is authored by FINBOURNE, the fields (columns) available to return or filter can be determined by running the following query:
select FieldName, DataType, IsMain, IsPrimaryKey, SampleValues, Description
from Sys.Field
where TableName = 'Some.Provider' and FieldType = 'Column';
Parameters
Data providers may have parameters that can be used to filter a Luminesce query as part of a standard WHERE
clause.
Note: Direct providers do not support parameters.
You must assign values to parameters unambiguously (not under an OR
clause), and only with the =
operator. For example:
select * from Some.Provider where SomeParameter = 12
For a Some.Provider
that is authored by FINBOURNE, available parameters can be determined by running the following query:
select FieldName, DataType, ParamDefaultValue, Description
from Sys.Field
where TableName = 'Some.Provider' and FieldType = 'Parameter';
Variables
You can use variables to create and populate arbitrary tables of data that can then be used as part of a Luminesce query for either a data provider or a direct provider.
This is similar to a combination of the standard SQL CREATE TABLE...INSERT INTO
statements.
Variable type | Explanation | Examples |
| Stores a table of any size |
|
| Only stores a scalar value (that is, the |
|
Type conversion
You can use the TYPES
statement before any SELECT
statement in a Luminesce query to force type conversion on columns. Note that this overrides the default SQLite behaviour of flexible typing.
Valid types are BIGINT
, INT
, DOUBLE
, DECIMAL
, BOOLEAN
, TEXT
, DATE
, TIME
and DATETIME
.
Example | Explanation |
| Returns columns as Int64, Int32, String and Boolean types respectively. |
| Returns columns 1, 2 and 4 as Int64, Int32 and Boolean types respectively, leaving column 3 to be inferred in the normal way. |
| Returns column 1 as text and leaves all the other columns to be inferred in the normal way. |
| Returns the result of the aggregate function as a double. |
| Returns column 1 as text, leaves all the other columns to be inferred in the normal way, and assigns the result to a table variable. |
FOR-EACH loops
You can use the CROSS APPLY
or OUTER APPLY
statement to emulate a FOR-EACH
loop. This is useful to execute a Luminesce query in parallel on a range of parameter inputs.
Statement | Explanation |
| Similar to |
| Similar to |
For example, the following query uses OUTER APPLY
with the Lusid.Portfolio.Holding provider to generate a holdings report for each of the last 3 days:
@days = select date('now', '-' || Value || ' days') as dt
from Tools.[Range] where number = 3 -- go back N days from today
and Start = 0; -- subtract 0 days, to include today (1 would exclude today)
select d.dt, results.* -- outer query
from @days as d
outer apply (
select h.^ -- inner query
from lusid.portfolio.holding as h
where h.EffectiveAt = d.dt
and h.PortfolioScope = 'EMEA'
and h.PortfolioCode = 'Equities'
) as results ;
Note the following:
Tables used in the inner or outer queries must be aliased, so for example
as d
in the outer query above andas h
in the inner query.Columns used in the
where
clause of the inner query must be explicitly selected in the outer query, so for exampled.dt
in the inner must be referenced asselect d.dt
in the outer. Referencing asselect d.*
would result in an error.There must be whitespace before the closing
;
character, for exampleas results ;
Variables (whether
@table
or@@scalar
) are not expanded in the inner query.There is no
ON
clause for eitherCROSS APPLY
orOUTER APPLY
.
JOIN clauses
Luminesce supports the following JOIN clauses: INNER JOIN
, LEFT (OUTER) JOIN
, CROSS JOIN
, FULL (OUTER) JOIN
.
Luminesce does not currently support RIGHT (OUTER) JOIN
.
Pausing query execution using WAIT
You can use the WAIT
modifier immediately after a select * from x
statement at any point in a query to wait for all the preceding code to execute before continuing, and optionally for a further specified number of seconds.
For example, if you create a custom view you may want to wait 5 seconds for it to appear in the Luminesce catalog before querying it:
@model_portfolios_view = use Sys.Admin.SetupView
--provider=Test.Example.TestHoldings
----
select PortfolioScope, PortfolioCode, BaseCurrency
from
Lusid.Portfolio
where
PortfolioType = 'Reference'
enduse;
--- Create the Test.Example.TestHoldings view
@result = select * from @model_portfolios_view;
--- Query the view, waiting 5 seconds for Luminesce to register it
select * from Test.Example.Testholdings wait 5 limit 1;
PRAGMAs
You can use one or more of the PRAGMA statements in the following table at any point in a query to override default Luminesce settings for that query. For example, to allow a query to run for 30 minutes before timing out, specify:
pragma TimeoutSec = 1800;
PRAGMA | Explanation |
| When true, parses the query, verifies access to provider(s) and, where possible, returns dummy data so you can examine the shape. However, does not execute the query, so (for example) write providers do not modify data. Designed for use in CI/CD pipelines where there may be downstream implications. |
| Defines the maximum number of parallel provider calls within a CROSS APPLY or OUTER APPLY statement in a query. Defaults to 5. |
| Defines the maximum number of variable calculations that may be performed in a query. Note if you experience a |
| Specifies the number of times to retry a provider if it is determined to be non-responsive. Defaults to 1. |
| Specifies a number of seconds to wait before a query times out. |
| Names a query. |
| Specifies the number of rows to use to determine the data type on returned data sets (defaults to 500). Note that for custom views it is better to prefer the |
| For use with the Luminesce |
| Specifies flags that can be given to the query coordinator to perform during execution for additional diagnostics. The following flags can be specified:
|
Converting to and from JSON
Luminesce supports the functions exposed by the JSON1 extension library.
You can use the dedicated Tools.JsonExpand provider to emulate the SQLite json.tree
function and convert a JSON document into a table of data objects.
To convert a table of data objects into JSON, you can use the SQLite json_group_array
and json_object
functions. This is required when using a provider that has a field with a Json
suffix, for example the PeriodsJson
field in the Lusid.Instrument.SimpleCashFlowLoan.Writer provider. The PeriodsJson
field is a text field that expects a flattened array of JSON objects as a value, each representing a loan period with PaymentDate
, Notional
and InterestAmount
fields. For example:
@periods = values
(#2022-03-01#, 100, 5),
(#2022-06-01#, 90, 4),
(#2022-09-01#, 50, 4.5),
(#2022-12-01#, 30, 2.0);
@@periodsArray = select
json_group_array(
json_object(
'PaymentDate', column1,
'Notional', column2,
'InterestAmount', column3
)
) from @periods;
@table_of_data = select 'MySimpleCashFlowLoan' as DisplayName, 'SimpleCashFlowLoan' as ClientInternal,
#2022-01-01# as StartDate, #2023-01-01# as MaturityDate, 'GBP' as DomCcy, @@periodsArray as PeriodsJson;
select * from Lusid.Instrument.SimpleCashFlowLoan.Writer where ToWrite = @table_of_data;
Parameterised queries
Most tools you can use to run Luminesce queries support parameterisation using the syntax:
:<unique-name>:<default-value>
Consider the following example:
select * from Lusid.Portfolio.Txn
where PortfolioScope = 'Finbourne-Examples'
and PortfolioCode = :ChooseFund:'UK-Equities'
and ShowNonActive = :ShowEverything:True
and TransactionDate > :FromDate:#2020-07-01#
and TotalConsideration > :ForMoreThan:1000
For example, when run from the Data Virtualisation > Query Editor or Saved Queries screen in the LUSID web app, the user is prompted to enter the following values at run time:
If the tool does not support parameterisation, the default value is used.