Search

Query Introspection API

API to introspect CDS QL statements in Java

Content

Introduction

The CDS Query Introspection API allows to extract key values and information on the CDS entities in references of CQN statements.

The CqnAnalyzer can be constructed from a CDS model.

import com.sap.cds.ql.cqn.CqnAnalyzer;

CdsModel cdsModel = context.getModel();
CqnAnalyzer cqnAnalyzer = CqnAnalyzer.create(cdsModel);

Usage

Given the following CDS model and CQL query

entity Orders {
  key OrderNo : String;
  Items       : Composition of many OrderItems on Items.parent = $self;
  ...
}
entity OrderItems {
  key ID : Integer;
  book   : Association to Books;
  ...
}

--CQL query
SELECT from Orders[OrderNo = 42].items[ID = 1]

the corresponding CQN statement can be analyzed using the analyze method of the CqnAnalyzer:

CqnStatement cqn = context.getCqn();

AnalysisResult result = cqnAnalyzer.analyze(cqn.ref());

Resolving CDS Entities

Based on the AnalysisResult, information on the CDS entities can be accessed through the Reflection API.

CdsEntity order = result.rootEntity();   // Orders
CdsEntity item  = result.targetEntity(); // OrderItems

Extracting Key Values

The key values of the entities can be extracted as a map:

Map<String, Object> rootKeys = result.rootKeys();
String orderNo = (String) rootKeys.get("OrderNo"); // 42

Map<String, Object> targetKeys  = result.targetKeys();
Integer itemId = (Integer) targetKeys.get("ID");   // 1

For CqnSelect, CqnUpdate, and CqnDelete, key values can also be extracted from the statement’s where condition.

--CQL query
SELECT from Orders[OrderNo = 42].items where ID = 3
CqnSelect select = context.getCqn();
Map<String, Object> targetKeys = cqnAnalyzer.analyze(select).targetKeys();
Integer itemId = (Integer) targetKeys.get("ID");   // 3

Extracting key values is only supported for noncomplex predicates where the values can be unambiguously determined.

Using the Iterator

The methods prefixed with root and target access the first resp. last segment of the CQN statement’s ref. If the ref has more than two segments, such as

--CQL query
SELECT from Orders[OrderNo = 42].items[ID = 1].book

the segment items can be analyzed using an iterator

Iterator<ResolvedSegment> iterator = result.iterator();
CdsEntity order = iterator.next().entity();
CdsEntity item  = iterator.next().entity();
CdsEntity book  = iterator.next().entity();

or a reverse iterator starting from the last segment:

Iterator<ResolvedSegment> iterator = result.reverse();
CdsEntity book  = iterator.next().entity();
CdsEntity item  = iterator.next().entity();
CdsEntity order = iterator.next().entity();

In the same way, also the key values for each segment can be extracted using the keys method instead of entity.