diff --git a/__tests__/__assets__/beershop-admin-service.sql b/__tests__/__assets__/beershop-admin-service.sql index 2749411b..f48f40e2 100644 --- a/__tests__/__assets__/beershop-admin-service.sql +++ b/__tests__/__assets__/beershop-admin-service.sql @@ -45,6 +45,13 @@ CREATE TABLE csw_TypeChecks ( PRIMARY KEY(ID) ); +CREATE TABLE csw_TypeChecksSibling ( + ID VARCHAR(36) NOT NULL, + dummyField VARCHAR(5000), + typeChecks_ID VARCHAR(36), + PRIMARY KEY(ID) +); + CREATE VIEW BeershopAdminService_Beers AS SELECT Beers_0.ID, Beers_0.createdAt, @@ -64,4 +71,4 @@ CREATE VIEW BeershopAdminService_Breweries AS SELECT Brewery_0.modifiedAt, Brewery_0.modifiedBy, Brewery_0.name -FROM csw_Brewery AS Brewery_0 \ No newline at end of file +FROM csw_Brewery AS Brewery_0; \ No newline at end of file diff --git a/__tests__/__assets__/cap-proj/.env.example b/__tests__/__assets__/cap-proj/.env.example index 6f08c26a..879f991f 100644 --- a/__tests__/__assets__/cap-proj/.env.example +++ b/__tests__/__assets__/cap-proj/.env.example @@ -1,3 +1,4 @@ # full URL to deployed cap-proj # aka /__tests__/__assets__/cap-proj scpServiceURL = https://-cap-proj-srv.cfapps.eu10.hana.ondemand.com +CDS_DEBUG = true \ No newline at end of file diff --git a/__tests__/__assets__/cap-proj/db/schema.cds b/__tests__/__assets__/cap-proj/db/schema.cds index 348cbb51..f2a86b3d 100644 --- a/__tests__/__assets__/cap-proj/db/schema.cds +++ b/__tests__/__assets__/cap-proj/db/schema.cds @@ -35,3 +35,9 @@ entity TypeChecks : cuid { type_LargeString : LargeString; virtual type_virtual : Integer; } + + +entity TypeChecksSibling : cuid { + dummyField : String; + typeChecks : Association to one TypeChecks; +} diff --git a/__tests__/__assets__/cap-proj/srv/beershop-service.cds b/__tests__/__assets__/cap-proj/srv/beershop-service.cds index ca441080..7eefaa98 100644 --- a/__tests__/__assets__/cap-proj/srv/beershop-service.cds +++ b/__tests__/__assets__/cap-proj/srv/beershop-service.cds @@ -6,8 +6,13 @@ service BeershopService { entity Breweries as projection on csw.Brewery; entity TypeChecks as projection on csw.TypeChecks; + @cds.redirection.target @odata.draft.enabled entity TypeChecksWithDraft as projection on csw.TypeChecks; + + @odata.draft.enabled + entity TypeChecksSibling as projection on csw.TypeChecksSibling; + } extend service BeershopService with { diff --git a/__tests__/__assets__/test.sql b/__tests__/__assets__/test.sql index ea5c261a..3a2019e5 100644 --- a/__tests__/__assets__/test.sql +++ b/__tests__/__assets__/test.sql @@ -39,6 +39,13 @@ CREATE TABLE csw_TypeChecks ( PRIMARY KEY(ID) ); +CREATE TABLE csw_TypeChecksSibling ( + ID VARCHAR(36) NOT NULL, + dummyField VARCHAR(5000), + typeChecks_ID VARCHAR(36), + PRIMARY KEY(ID) +); + CREATE TABLE DRAFT_DraftAdministrativeData ( DraftUUID VARCHAR(36) NOT NULL, CreationDateTime TIMESTAMPTZ, @@ -73,6 +80,17 @@ CREATE TABLE BeershopService_TypeChecksWithDraft_drafts ( PRIMARY KEY(ID) ); +CREATE TABLE BeershopService_TypeChecksSibling_drafts ( + ID VARCHAR(36) NOT NULL, + dummyField VARCHAR(5000) NULL, + typeChecks_ID VARCHAR(36) NULL, + IsActiveEntity BOOLEAN, + HasActiveEntity BOOLEAN, + HasDraftEntity BOOLEAN, + DraftAdministrativeData_DraftUUID VARCHAR(36) NOT NULL, + PRIMARY KEY(ID) +); + CREATE VIEW BeershopService_Beers AS SELECT Beers_0.ID, Beers_0.createdAt, @@ -128,6 +146,12 @@ CREATE VIEW BeershopService_TypeChecksWithDraft AS SELECT TypeChecks_0.type_LargeString FROM csw_TypeChecks AS TypeChecks_0; +CREATE VIEW BeershopService_TypeChecksSibling AS SELECT + TypeChecksSibling_0.ID, + TypeChecksSibling_0.dummyField, + TypeChecksSibling_0.typeChecks_ID +FROM csw_TypeChecksSibling AS TypeChecksSibling_0; + CREATE VIEW BeershopService_DraftAdministrativeData AS SELECT DraftAdministrativeData.DraftUUID, DraftAdministrativeData.CreationDateTime, @@ -137,4 +161,4 @@ CREATE VIEW BeershopService_DraftAdministrativeData AS SELECT DraftAdministrativeData.LastChangedByUser, DraftAdministrativeData.InProcessByUser, DraftAdministrativeData.DraftIsProcessedByMe -FROM DRAFT_DraftAdministrativeData AS DraftAdministrativeData \ No newline at end of file +FROM DRAFT_DraftAdministrativeData AS DraftAdministrativeData; \ No newline at end of file diff --git a/__tests__/lib/pg/draft.test.js b/__tests__/lib/pg/draft.test.js index 6340e71c..5e5c04a5 100644 --- a/__tests__/lib/pg/draft.test.js +++ b/__tests__/lib/pg/draft.test.js @@ -4,7 +4,7 @@ const deploy = require('@sap/cds/lib/deploy') // mock (package|.cdsrc).json entries cds.env.requires.db = { kind: 'postgres' } cds.env.requires.postgres = { - impl: './cds-pg', // hint: not really sure as to why this is, but... + impl: './cds-pg' // hint: not really sure as to why this is, but... } // default (single) test environment is local, @@ -23,7 +23,7 @@ describe.each(suiteEnvironments)( kind: 'postgres', dialect: 'plain', model: this._model, - credentials: credentials, + credentials: credentials } // only bootstrap in local mode as scp app is deployed and running @@ -49,13 +49,24 @@ describe.each(suiteEnvironments)( `${basepath}/BeershopService.draftEdit?$expand=DraftAdministrativeData($select=DraftUUID,InProcessByUser)` ) .send({ - PreserveChanges: true, + PreserveChanges: true }) expect(response.status).toStrictEqual(201) const responseGet = await request.get(basepath) expect(responseGet.status).toStrictEqual(200) }) + + test(' -> Draft entity referencing another draft entity on matchcode call', async () => { + const oQuery = + '/beershop/TypeChecksSibling?$filter=(IsActiveEntity eq false or SiblingEntity/IsActiveEntity eq null)&$expand=typeChecks($select=type_String)' + + const response = await request.get(oQuery).send({ + PreserveChanges: true + }) + + expect(response.status).toStrictEqual(200) + }) }) } ) diff --git a/__tests__/lib/pg/service-admin.test.js b/__tests__/lib/pg/service-admin.test.js index fce191ef..47323f16 100644 --- a/__tests__/lib/pg/service-admin.test.js +++ b/__tests__/lib/pg/service-admin.test.js @@ -64,7 +64,7 @@ describe.each(suiteEnvironments)( const response = await request.get('/beershop/') expect(response.status).toStrictEqual(200) - expect(response.body.value.length).toStrictEqual(4) + expect(response.body.value.length).toStrictEqual(5) }) describe('OData admin: CREATE', () => { diff --git a/__tests__/lib/pg/service.test.js b/__tests__/lib/pg/service.test.js index 272e0e9e..38db2d19 100644 --- a/__tests__/lib/pg/service.test.js +++ b/__tests__/lib/pg/service.test.js @@ -69,7 +69,7 @@ describe.each(suiteEnvironments)( const response = await request.get('/beershop/') expect(response.status).toStrictEqual(200) - expect(response.body.value.length).toStrictEqual(4) + expect(response.body.value.length).toStrictEqual(5) }) describe('odata: GET -> sql: SELECT', () => { diff --git a/lib/pg/sql-builder/SelectBuilder.js b/lib/pg/sql-builder/SelectBuilder.js index af51aac5..672d04ab 100644 --- a/lib/pg/sql-builder/SelectBuilder.js +++ b/lib/pg/sql-builder/SelectBuilder.js @@ -180,9 +180,13 @@ class PGSelectBuilder extends SelectBuilder { } // an as (alias) should always be passed Postgres need it for its select statements - if (element.as || as) { + if (element.as) { // identifier - res.sql += ` ${this._quoteElement(element.as || as)}` + res.sql += ` ${this._quoteElement(element.as)}` + } else { + if (as && this._options.objectKey !== 'xpr') { + res.sql += ` ${this._quoteElement(as)}` + } } this._outputObj.values.push(...res.values)