@cap-js/db-service 2.8.1 → 2.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@
4
4
  - The format is based on [Keep a Changelog](http://keepachangelog.com/).
5
5
  - This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [2.8.2](https://github.com/cap-js/cds-dbs/compare/db-service-v2.8.1...db-service-v2.8.2) (2026-02-03)
8
+
9
+
10
+ ### Fixed
11
+
12
+ * compare conversion for right hand `null` transformation ([#1469](https://github.com/cap-js/cds-dbs/issues/1469)) ([ec1d0c6](https://github.com/cap-js/cds-dbs/commit/ec1d0c6fa08db1f75e9b72eed382a507b49815cc))
13
+ * **cqn4sql:** calculated elements with function expr in from ([#1452](https://github.com/cap-js/cds-dbs/issues/1452)) ([970407e](https://github.com/cap-js/cds-dbs/commit/970407e29e4c98ee9c25d15277dff80c246b9523))
14
+ * hierarchy with $top ([#1460](https://github.com/cap-js/cds-dbs/issues/1460)) ([dfc6226](https://github.com/cap-js/cds-dbs/commit/dfc62261681ced388e9c35aa8ce3e49e1c09f4e2))
15
+ * search aggregate functions ([#1463](https://github.com/cap-js/cds-dbs/issues/1463)) ([a8db1f3](https://github.com/cap-js/cds-dbs/commit/a8db1f38e219bd7818c3cfc9f45e108bcab1dd95))
16
+ * support all types for casting in queries ([#1481](https://github.com/cap-js/cds-dbs/issues/1481)) ([8392232](https://github.com/cap-js/cds-dbs/commit/8392232aafdcfa025a7dce597bf65fb6344acd1f))
17
+
7
18
  ## [2.8.1](https://github.com/cap-js/cds-dbs/compare/db-service-v2.8.0...db-service-v2.8.1) (2025-12-19)
8
19
 
9
20
 
package/lib/cqn2sql.js CHANGED
@@ -298,6 +298,7 @@ class CQN2SQLRenderer {
298
298
  const clone = q.clone()
299
299
  clone.columns(keys)
300
300
  clone.SELECT.recurse = undefined
301
+ clone.SELECT.limit = undefined
301
302
  clone.SELECT.expand = undefined // omits JSON
302
303
  where = [{ list: keys }, 'in', clone]
303
304
  }
@@ -1224,7 +1225,7 @@ class CQN2SQLRenderer {
1224
1225
  ? _inline_null(xpr[i + 1]) || 'is'
1225
1226
  : '='
1226
1227
 
1227
- // Translate == to IS NOT NULL for rhs operand being NULL literal, otherwise ...
1228
+ // Translate == to IS NULL for rhs operand being NULL literal, otherwise ...
1228
1229
  // Translate == to IS NOT DISTINCT FROM, unless both operands cannot be NULL
1229
1230
  if (x === '==') return xpr[i + 1]?.val === null
1230
1231
  ? _inline_null(xpr[i + 1]) || 'is'
@@ -1232,7 +1233,7 @@ class CQN2SQLRenderer {
1232
1233
  ? '='
1233
1234
  : this.is_not_distinct_from_
1234
1235
 
1235
- // Translate != to IS NULL for rhs operand being NULL literal, otherwise...
1236
+ // Translate != to IS NOT NULL for rhs operand being NULL literal, otherwise...
1236
1237
  // Translate != to IS DISTINCT FROM, unless both operands cannot be NULL
1237
1238
  if (x === '!=') return xpr[i + 1]?.val === null
1238
1239
  ? _inline_null(xpr[i + 1]) || 'is not'
@@ -5,19 +5,7 @@ const cds = require('@sap/cds')
5
5
  const JoinTree = require('./join-tree')
6
6
  const { pseudos } = require('./pseudos')
7
7
  const { isCalculatedOnRead, getImplicitAlias, getModelUtils, defineProperty, hasOwnSkip } = require('../utils')
8
- const cdsTypes = cds.linked({
9
- definitions: {
10
- Timestamp: { type: 'cds.Timestamp' },
11
- DateTime: { type: 'cds.DateTime' },
12
- Date: { type: 'cds.Date' },
13
- Time: { type: 'cds.Time' },
14
- String: { type: 'cds.String' },
15
- Decimal: { type: 'cds.Decimal' },
16
- Integer: { type: 'cds.Integer' },
17
- Boolean: { type: 'cds.Boolean' },
18
- },
19
- }).definitions
20
- for (const each in cdsTypes) cdsTypes[`cds.${each}`] = cdsTypes[each]
8
+ const cdsTypes = cds.builtin.types
21
9
  /**
22
10
  * @param {import('@sap/cds/apis/cqn').Query|string} originalQuery
23
11
  * @param {import('@sap/cds/apis/csn').CSN} [model]
@@ -746,7 +734,7 @@ function infer(originalQuery, model) {
746
734
  const expandElements = resolveExpand(inlineCol)
747
735
  elements = { ...elements, [name]: expandElements }
748
736
  } else if (inlineCol.val) {
749
- elements[name] = { ...getCdsTypeForVal(inlineCol.val) }
737
+ elements[name] = getCdsTypeForVal(inlineCol.val)
750
738
  } else if (inlineCol.func) {
751
739
  elements[name] = {}
752
740
  } else {
@@ -867,7 +855,7 @@ function infer(originalQuery, model) {
867
855
  arg,
868
856
  null,
869
857
  { definition: parentElementDefinition, target: parentElementDefinition },
870
- { inCalcElement: true },
858
+ { inCalcElement: true, ...context },
871
859
  )
872
860
  const basePath =
873
861
  column.$refLinks?.length > 1
@@ -1091,7 +1079,10 @@ function infer(originalQuery, model) {
1091
1079
  if ($refLinks?.[$refLinks.length - 1].definition.elements)
1092
1080
  // no cast on structure
1093
1081
  cds.error`Structured elements can't be cast to a different type`
1094
- thing.cast = cdsTypes[cast.type] || cast
1082
+ const cdsType = cdsTypes[cast.type]
1083
+ thing.cast = cdsType ? new cdsType.constructor(cast) : cast
1084
+ if (cdsType)
1085
+ thing.cast.type = cdsType._type
1095
1086
  return thing.cast
1096
1087
  }
1097
1088
 
@@ -1121,11 +1112,11 @@ function infer(originalQuery, model) {
1121
1112
  // if(val === null) return {type:'cds.String'}
1122
1113
  switch (typeof val) {
1123
1114
  case 'string':
1124
- return cdsTypes.String
1115
+ return new cdsTypes.String.constructor()
1125
1116
  case 'boolean':
1126
- return cdsTypes.Boolean
1117
+ return new cdsTypes.Boolean.constructor()
1127
1118
  case 'number':
1128
- return Number.isSafeInteger(val) ? cdsTypes.Integer : cdsTypes.Decimal
1119
+ return Number.isSafeInteger(val) ? new cdsTypes.Integer.constructor() : new cdsTypes.Decimal.constructor()
1129
1120
  default:
1130
1121
  return {}
1131
1122
  }
@@ -1,22 +1,23 @@
1
1
  'use strict'
2
2
 
3
- // REVISIT: we should always return cds.linked elements
4
- // > e.g. cds.linked({definitions:{pseudos}})
3
+ const cds = require('@sap/cds')
4
+ const { String, Timestamp } = cds.builtin.types
5
+
5
6
  const pseudos = {
6
7
  elements: {
7
8
  $user: {
8
9
  elements: {
9
- id: { type: 'cds.String' },
10
- locale: { type: 'cds.String' }, // deprecated
11
- tenant: { type: 'cds.String' }, // deprecated
10
+ id: String,
11
+ locale: String, // deprecated
12
+ tenant: String, // deprecated
12
13
  },
13
14
  },
14
- $now: { type: 'cds.Timestamp' },
15
- $at: { type: 'cds.Timestamp' },
16
- $from: { type: 'cds.Timestamp' },
17
- $to: { type: 'cds.Timestamp' },
18
- $locale: { type: 'cds.String' },
19
- $tenant: { type: 'cds.String' },
15
+ $now: Timestamp,
16
+ $at: Timestamp,
17
+ $from: Timestamp,
18
+ $to: Timestamp,
19
+ $locale: String,
20
+ $tenant: String,
20
21
  },
21
22
  }
22
23
 
package/lib/search.js CHANGED
@@ -174,7 +174,7 @@ const computeColumnsToBeSearched = (cqn, entity = { __searchableColumns: [] }) =
174
174
  // only strings can be searched
175
175
  if (element?.type !== DEFAULT_SEARCHABLE_TYPE) {
176
176
  if (column.xpr) return
177
- if (column.func && !(column.func in aggregateFunctions)) return
177
+ if (column.func && !(column.func.toUpperCase() in aggregateFunctions)) return
178
178
  }
179
179
 
180
180
  const searchTerm = {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/db-service",
3
- "version": "2.8.1",
3
+ "version": "2.8.2",
4
4
  "description": "CDS base database service",
5
5
  "homepage": "https://github.com/cap-js/cds-dbs/tree/main/db-service#cds-base-database-service",
6
6
  "repository": {