Skip to content

Conversation

@patricebender
Copy link
Contributor

TBD

Comment on lines 37 to 39
No matter where `CXL` is used, it always manifests in queries.
For example, [a calculated element](./cdl/#calculated-elements) defined in an entity will be resolved
to the respective calculation in the generated query when the entity is queried.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use expressions in various other places

  • translated to EDMX-expressions
  • to define projections between types
  • projections can be resolved at runtime (runtime views)
  • expressions can be evaluated in memory

Copy link
Contributor

@Akatuoro Akatuoro Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query does not mean that it is a database query. There can be multiple vehicles for an expression. Conceptually though, it can be understood as part of a query - whether it is either sent to the database, converted to edmx (and then sent to the backend again), or evaluated in memory.
This is an important point though. Expressions are not only meant for database queries.

Keeping this open -> happy for suggestions on how to formulate this.

@renejeglinsky
Copy link
Contributor

There's one example where it's not the text but the box that is clickable. Is that on purpose?
image

@Akatuoro
Copy link
Contributor

Akatuoro commented Jan 9, 2026

I still think this documentation is way to much focused on explaining how CQL is converted to SQL. Instead we should provide a documentation that explains the fundamentals of the expression language:

Values

  • literals

  • refs

    • paths

      • filtered paths -> predicates
  • parameters

  • value functions

  • value expressions

Predicates

  • comparison predicates
  • connectives (AND, OR)
  • negation
  • Boolean functions

I would not know why you need SQL to explain any of this.

The samples all have the corresponding SQL to make transparent what actually happens in the background. This is quite important for humans and especially for LLMs. The SQL is always hidden behind an extra tab, so it is not the focus.

If CQL (which CXL is a part of) was really its own language, it would make sense to describe and specify everything in detail from the ground up. Since it is based on SQL, we can use that fact to build on pre-existing knowledge.

To the structure of Value vs. Predicate... I don't agree. Predicates are also "values"... or rather, expressions... simply boolean expressions. There are some constructs which require that an expression returns a boolean (case when, ternary, filters, ...), but this boolean can also come from a literal, a ref etc.

@patricebender patricebender requested a review from danjoa January 13, 2026 16:03
Copy link
Member

@danjoa danjoa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new shape looks much better :-)

cds/cxl.md Outdated
| `count(x)` | Returns the count of non-null values of `x`. |
| `countdistinct(x)` | Returns the count of distinct non-null values of `x`. |

CAP supports a set of [portable functions](../guides/databases/cql-to-sql.md#portable-functions) that can be used in all expressions. Those functions are passed through to the underlying database, allowing you to leverage the same functions for different databases, which greatly enhances portability.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather define the portable functions here (as they are DB-independent and also apply for to remote OData calls). Then link from the database guide to here.

patricebender and others added 13 commits January 14, 2026 14:29
```js
> cds.parse.xpr`TimeStamp'2025-12-12'`
[ { val: '2025-12-12', literal: 'timestamp' } ]
> cds.parse.xpr`Time'2025-12-12'`
[ { val: '2025-12-12', literal: 'time' } ]
> cds.parse.xpr`Date'2025-12-12'`
[ { val: '2025-12-12', literal: 'date' } ]
> cds.parse.xpr`DateTime'2025-12-12'`
Uncaught Error: CDS compilation failed
In 'DateTime'2025-12-12'' at 9-21: Error: Mismatched ‹String›, expecting ‘.’, ‘(’, ‘[’, ‘!=’, ‘?’, ‘*’, ‘+’, ‘-’, ‘/’, ‘<’, ‘<=’, ‘<>’, ‘=’, ‘==’, ‘>’, ‘>=’, ‘||’, ‘and’, ‘between’, ‘in’, ‘is’, ‘like’, ‘not’, ‘or’, ‘over’, ‹EOF›
    at Object.throwWithError (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds-compiler/lib/base/messages.js:571:13)
    at parseExpr (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds-compiler/lib/main.js:74:20)
    at Object.expr (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds-compiler/lib/main.js:129:24)
    at expr (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds/lib/compile/parse.js:43:27)
    at exports.ttl (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds/lib/compile/parse.js:83:15)
    at Function.expr (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds/lib/compile/parse.js:37:27)
    at exports.xpr (/Users/patricebender/SAPDevelop/cxl-bookshop/node_modules/@sap/cds/lib/compile/parse.js:52:19)
```
@Akatuoro Akatuoro merged commit c4554c0 into main Jan 15, 2026
8 checks passed
@Akatuoro Akatuoro deleted the cxl branch January 15, 2026 11:35
extend Authors with {
age = years_between(dateOfBirth, coalesce(dateOfDeath, date( $now )));
extend Books with {
total = price * stock;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a type

Suggested change
total = price * stock;
total = price * stock : Decimal(8,2);

Comment on lines +301 to +302
> cds.parse.expr ` TimeStamp'2026-01-14T10:30:00Z' `
{ val: '2026-01-14T10:30:00Z', literal: 'timestamp' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ISO 8601. Is this portable on all DBs? I.e., will

entity Start : cuid {
  start : Timestamp default TimeStamp'2026-01-14T10:30:00Z'
}

actually work?

Or rather use ISO/IEC 9075

Suggested change
> cds.parse.expr ` TimeStamp'2026-01-14T10:30:00Z' `
{ val: '2026-01-14T10:30:00Z', literal: 'timestamp' }
> cds.parse.expr ` TimeStamp'2026-01-14 10:30:00' `
{ val: '2026-01-14 10:30:00', literal: 'timestamp' }

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CAP Java additionally supports these literal types

  • number
  • x
  • hex
  • boolean
  • string
  • vector


[Learn more about the `exists` predicate.](./cql.md#exists-predicate){.learn-more}

The `exists` predicate can be further enhanced by [combining it with infix filters](#exists-infix-filter).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap as "tip"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants