@sap/cds-dk 10.1.2 → 10.2.1
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 +54 -0
- package/bin/add.js +7 -2
- package/bin/bind.js +5 -6
- package/bin/bindings.js +35 -0
- package/bin/build.js +11 -6
- package/bin/compile/index.js +1 -0
- package/bin/completion/index.js +10 -448
- package/bin/completion/scripts/cds.fish +28 -19
- package/bin/completion/scripts/cds.ps1 +30 -29
- package/bin/completion/scripts/cds.sh +26 -23
- package/bin/completion/scripts/cds.zsh +26 -23
- package/bin/debug.js +3 -3
- package/bin/deploy/index.js +3 -3
- package/bin/deploy/to-hana/hana.js +6 -5
- package/bin/deploy/to-hana/hdiDeployUtil.js +25 -14
- package/bin/env.js +0 -1
- package/bin/eval.js +9 -5
- package/bin/export.js +6 -4
- package/bin/help/export.md +28 -4
- package/bin/import.js +6 -5
- package/bin/inspect.js +0 -1
- package/bin/login.js +28 -3
- package/bin/repl.js +82 -26
- package/bin/run.js +6 -7
- package/bin/serve.js +6 -7
- package/bin/up.js +10 -5
- package/bin/upgrade/steps/install.js +6 -6
- package/bin/version.js +1 -1
- package/bin/watch/index.js +1 -0
- package/bin/watch/vite-watch.js +12 -6
- package/lib/bind/shared.js +1 -1
- package/lib/build/index.js +11 -7
- package/lib/build/plugins/featureToggles.js +2 -2
- package/lib/build/plugins/hana/index.js +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +7 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/api-rule.yaml +1 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +4 -4
- package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +13 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +7 -1
- package/lib/build/plugins/java/index.js +5 -1
- package/lib/build/plugins/nodejs/index.js +5 -1
- package/lib/build/util.js +4 -5
- package/lib/env/schemas/cds-rc.js +5 -0
- package/lib/import/importapi.js +2 -3
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +9 -3
- package/lib/init/plugin.js +1 -1
- package/lib/init/projectReader.js +16 -12
- package/lib/init/registries/mta.js +0 -6
- package/lib/init/template/ai/index.js +4 -4
- package/lib/init/template/ams/files/extensionDeveloper.dcl +6 -0
- package/lib/init/template/ams/files/mta.yaml.hbs +6 -0
- package/lib/init/template/ams/files/sidecar.package.json.hbs +5 -0
- package/lib/init/template/ams/index.js +42 -40
- package/lib/init/template/app-frontend/files/mta.yaml.hbs +2 -0
- package/lib/init/template/app-frontend/files/ui5.yaml.hbs +0 -4
- package/lib/init/template/app-frontend/index.js +29 -24
- package/lib/init/template/application-logging/index.js +6 -6
- package/lib/init/template/approuter/files/values.yaml.hbs +0 -9
- package/lib/init/template/approuter/index.js +19 -13
- package/lib/init/template/attachments/index.js +3 -3
- package/lib/init/template/audit-logging/index.js +4 -4
- package/lib/init/template/cloud-logging/index.js +12 -6
- package/lib/init/template/completion/completionSetup.js +19 -6
- package/lib/init/template/connectivity/index.js +3 -3
- package/lib/init/template/data/as-csv.js +7 -4
- package/lib/init/template/data/as-json.js +77 -20
- package/lib/init/template/destination/index.js +12 -9
- package/lib/init/template/dynatrace/index.js +5 -5
- package/lib/init/template/enterprise-messaging/index.js +6 -6
- package/lib/init/template/enterprise-messaging-shared/index.js +4 -4
- package/lib/init/template/extensibility/index.js +2 -2
- package/lib/init/template/extension/index.js +26 -0
- package/lib/init/template/github-actions/index.js +3 -3
- package/lib/init/template/hana/files/package.json.hbs +3 -2
- package/lib/init/template/hana/index.js +5 -5
- package/lib/init/template/hana-serverless/index.js +3 -3
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +2 -0
- package/lib/init/template/html5-repo/files/ui5.yaml.hbs +0 -4
- package/lib/init/template/html5-repo/index.js +80 -40
- package/lib/init/template/http/index.js +1 -1
- package/lib/init/template/ias/index.js +7 -7
- package/lib/init/template/initial/files/.gitignore.hbs +1 -0
- package/lib/init/template/kafka/index.js +3 -3
- package/lib/init/template/kyma/index.js +7 -9
- package/lib/init/template/malware-scanner/index.js +3 -3
- package/lib/init/template/mta/index.js +6 -3
- package/lib/init/template/multitenancy/index.js +6 -7
- package/lib/init/template/notifications/index.js +2 -2
- package/lib/init/template/portal/index.js +16 -10
- package/lib/init/template/postgres/index.js +5 -5
- package/lib/init/template/react/files/index.html.hbs +1 -1
- package/lib/init/template/react/files/package.json.hbs +3 -2
- package/lib/init/template/react/files/src/{App.jsx.hbs → App.{{jsxExtension}}.hbs} +8 -2
- package/lib/init/template/react/files/src/{main.jsx → main.{{jsxExtension}}.hbs} +2 -2
- package/lib/init/template/react/files/{vite.config.js.hbs → vite.config.{{extension}}.hbs} +2 -3
- package/lib/init/template/react/index.js +22 -5
- package/lib/init/template/react/typescript/src/vite-env.d.ts +1 -0
- package/lib/init/template/react/typescript/tsconfig.json.hbs +16 -0
- package/lib/init/template/redis/index.js +2 -2
- package/lib/init/template/sample/files/app/index.html.hbs +18 -0
- package/lib/init/template/sample/index.js +1 -0
- package/lib/init/template/side-by-side-extensibility/index.js +6 -3
- package/lib/init/template/typescript/files/tsconfig.json +3 -1
- package/lib/init/template/vue/files/index.html.hbs +1 -1
- package/lib/init/template/vue/files/package.json.hbs +2 -1
- package/lib/init/template/vue/files/src/App.vue.hbs +8 -2
- package/lib/init/template/vue/files/{vite.config.js.hbs → vite.config.{{extension}}.hbs} +2 -3
- package/lib/init/template/vue/index.js +19 -5
- package/lib/init/template/vue/typescript/tsconfig.json +11 -0
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +2 -2
- package/lib/init/template/workzone-standard/index.js +29 -27
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +1 -1
- package/lib/init/template/xsuaa/files/values.yaml.hbs +1 -1
- package/lib/init/template/xsuaa/index.js +34 -22
- package/lib/mtx/auth_manager.js +8 -2
- package/lib/mtx/browser_login.js +181 -0
- package/lib/mtx/params.js +6 -0
- package/lib/mtx/push.js +7 -1
- package/lib/mtx/settings_manager.js +29 -4
- package/lib/util/cf.js +44 -8
- package/lib/util/fs.js +2 -2
- package/node_modules/@cap-js/asyncapi/README.md +4 -14
- package/node_modules/@cap-js/asyncapi/cds-plugin.js +12 -0
- package/node_modules/@cap-js/asyncapi/index.js +3 -2
- package/node_modules/@cap-js/asyncapi/lib/compile/components/messages/index.js +4 -2
- package/node_modules/@cap-js/asyncapi/lib/compile/components/schemas/definition.js +11 -1
- package/node_modules/@cap-js/asyncapi/lib/compile/components/schemas/utils.js +16 -0
- package/node_modules/@cap-js/asyncapi/lib/compile/utils.js +4 -3
- package/node_modules/@cap-js/asyncapi/lib/import/importAsyncAPI.js +34 -0
- package/node_modules/@cap-js/asyncapi/lib/import/index.js +18 -0
- package/node_modules/@cap-js/asyncapi/lib/import/message.js +9 -0
- package/node_modules/@cap-js/asyncapi/lib/import/parserContext.js +368 -0
- package/node_modules/@cap-js/asyncapi/lib/import/utils.js +85 -0
- package/node_modules/@cap-js/asyncapi/package.json +89 -1
- package/node_modules/@cap-js/db-service/CHANGELOG.md +10 -0
- package/node_modules/@cap-js/db-service/lib/cqn2pql.js +4 -0
- package/node_modules/@cap-js/db-service/lib/cqn2sql.js +3 -0
- package/node_modules/@cap-js/db-service/lib/cqn4sql.js +8 -23
- package/node_modules/@cap-js/db-service/lib/infer/index.js +20 -27
- package/node_modules/@cap-js/db-service/package.json +1 -1
- package/node_modules/@cap-js/openapi/cds-plugin.js +12 -0
- package/node_modules/@cap-js/openapi/index.js +3 -1
- package/node_modules/@cap-js/openapi/lib/compile/csdl2openapi.js +652 -413
- package/node_modules/@cap-js/openapi/lib/compile/diagram.js +16 -13
- package/node_modules/@cap-js/openapi/lib/compile/index.js +10 -7
- package/node_modules/@cap-js/openapi/lib/compile/property-util.js +51 -0
- package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/importOpenAPI.js +12 -9
- package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/index.js +4 -3
- package/node_modules/@cap-js/openapi/package.json +71 -3
- package/node_modules/@cap-js/sqlite/CHANGELOG.md +9 -0
- package/node_modules/@cap-js/sqlite/package.json +3 -3
- package/node_modules/@isaacs/fs-minipass/LICENSE +15 -0
- package/node_modules/@isaacs/fs-minipass/README.md +71 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.d.ts +118 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js +430 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/package.json +3 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.d.ts +118 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.d.ts.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.js +420 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.js.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/package.json +3 -0
- package/node_modules/@isaacs/fs-minipass/package.json +72 -0
- package/node_modules/@sap/cds/CHANGELOG.md +62 -1
- package/node_modules/@sap/cds/_i18n/messages_ar.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_bg.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_cs.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_da.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_de.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_el.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_en.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_es.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_es_MX.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_fi.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_fr.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_he.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_hr.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_hu.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_it.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ja.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_kk.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ko.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ms.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_nl.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_no.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_pl.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_pt.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ro.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ru.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sh.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sk.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sl.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sv.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_th.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_tr.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_uk.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_vi.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_zh_CN.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_zh_TW.properties +1 -0
- package/node_modules/@sap/cds/app/index-client.js +164 -0
- package/node_modules/@sap/cds/app/index.css +598 -87
- package/node_modules/@sap/cds/app/index.html +54 -30
- package/node_modules/@sap/cds/app/index.js +311 -67
- package/node_modules/@sap/cds/app/table.html +226 -0
- package/node_modules/@sap/cds/app/table.js +302 -0
- package/node_modules/@sap/cds/bin/serve.js +3 -2
- package/node_modules/@sap/cds/eslint.config.mjs +2 -0
- package/node_modules/@sap/cds/lib/compile/cdsc.js +7 -0
- package/node_modules/@sap/cds/lib/compile/for/embeddings.js +27 -0
- package/node_modules/@sap/cds/lib/compile/load.js +2 -2
- package/node_modules/@sap/cds/lib/compile/minify.js +17 -4
- package/node_modules/@sap/cds/lib/compile/parse.js +3 -0
- package/node_modules/@sap/cds/lib/compile/resolve.js +16 -14
- package/node_modules/@sap/cds/lib/core/classes.js +1 -0
- package/node_modules/@sap/cds/lib/dbs/cds-deploy.js +4 -5
- package/node_modules/@sap/cds/lib/env/cds-env.js +132 -70
- package/node_modules/@sap/cds/lib/env/cds-requires/auth-strategies.js +62 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/databases.js +49 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/embeddings.js +8 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/index.js +27 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/messaging.js +82 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/platform.js +23 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/queues.js +34 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/services.js +32 -0
- package/node_modules/@sap/cds/lib/env/defaults.js +9 -1
- package/node_modules/@sap/cds/lib/env/schemas/cds-package.js +0 -2
- package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +3 -3
- package/node_modules/@sap/cds/lib/env/schemas/index.js +4 -4
- package/node_modules/@sap/cds/lib/i18n/files.js +4 -4
- package/node_modules/@sap/cds/lib/i18n/locale.js +1 -1
- package/node_modules/@sap/cds/lib/index.js +9 -9
- package/node_modules/@sap/cds/lib/log/cds-log.js +3 -3
- package/node_modules/@sap/cds/lib/ql/SELECT.js +2 -0
- package/node_modules/@sap/cds/lib/ql/UPDATE.js +1 -1
- package/node_modules/@sap/cds/lib/ql/cds.ql-Query.js +4 -1
- package/node_modules/@sap/cds/lib/ql/core/@types/cqn.d.ts +146 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/exprs.d.ts +51 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/index.d.ts +29 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/package.json +7 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/delete.d.ts +8 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/insert.d.ts +19 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/select.d.ts +24 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/update.d.ts +10 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/query.d.ts +18 -0
- package/node_modules/@sap/cds/lib/ql/core/cql/parser.min.js +1 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/index.js +69 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/cache.js +34 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/call-action.js +6 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/delete.js +8 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/insert.js +26 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/select.js +22 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/update.js +26 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/query.js +85 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/xl/fluent.js +47 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/xl/ttl.js +24 -0
- package/node_modules/@sap/cds/lib/ql/core/license +201 -0
- package/node_modules/@sap/cds/lib/ql/core/package.json +24 -0
- package/node_modules/@sap/cds/lib/ql/core/readme.md +99 -0
- package/node_modules/@sap/cds/lib/ql/core/upstream.json +5 -0
- package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
- package/node_modules/@sap/cds/lib/srv/bindings.js +111 -115
- package/node_modules/@sap/cds/lib/srv/cds-connect.js +11 -10
- package/node_modules/@sap/cds/lib/srv/cds-serve.js +16 -7
- package/node_modules/@sap/cds/lib/srv/cds.Service.js +13 -7
- package/node_modules/@sap/cds/lib/srv/factory.js +8 -10
- package/node_modules/@sap/cds/lib/srv/middlewares/auth/ias-auth.js +35 -32
- package/node_modules/@sap/cds/lib/srv/middlewares/auth/jwt-auth.js +5 -1
- package/node_modules/@sap/cds/lib/srv/middlewares/auth/mocked-users.js +1 -1
- package/node_modules/@sap/cds/lib/srv/protocols/hcql.js +230 -79
- package/node_modules/@sap/cds/lib/srv/protocols/http.js +7 -3
- package/node_modules/@sap/cds/lib/srv/protocols/index.js +7 -2
- package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +2 -2
- package/node_modules/@sap/cds/lib/utils/cds-utils.js +50 -0
- package/node_modules/@sap/cds/lib/utils/csv-reader.js +2 -2
- package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +18 -27
- package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +1 -1
- package/node_modules/@sap/cds/libx/_runtime/common/utils/rewriteAsterisks.js +1 -1
- package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +121 -84
- package/node_modules/@sap/cds/libx/_runtime/messaging/common-utils/authorizedRequest.js +24 -1
- package/node_modules/@sap/cds/libx/_runtime/messaging/common-utils/connections.js +45 -39
- package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +2 -2
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +3 -2
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +11 -6
- package/node_modules/@sap/cds/libx/odata/ODataAdapter.js +1 -1
- package/node_modules/@sap/cds/libx/odata/middleware/create.js +4 -0
- package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +1 -1
- package/node_modules/@sap/cds/libx/odata/middleware/operation.js +3 -0
- package/node_modules/@sap/cds/libx/odata/middleware/parse.js +9 -0
- package/node_modules/@sap/cds/libx/odata/middleware/read.js +6 -0
- package/node_modules/@sap/cds/libx/odata/middleware/update.js +5 -1
- package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +3 -3
- package/node_modules/@sap/cds/libx/odata/parse/multipartToJson.js +1 -1
- package/node_modules/@sap/cds/libx/odata/utils/ieee754.js +20 -0
- package/node_modules/@sap/cds/libx/queue/TaskRunner.js +22 -5
- package/node_modules/@sap/cds/libx/queue/api.js +1 -1
- package/node_modules/@sap/cds/libx/queue/index.js +3 -1
- package/node_modules/@sap/cds/libx/queue/processing.js +5 -0
- package/node_modules/@sap/cds/libx/rest/RestAdapter.js +1 -0
- package/node_modules/@sap/cds/package.json +2 -2
- package/node_modules/@sap/cds/server.js +1 -0
- package/node_modules/@sap/cds/srv/ucl-service.cds +1 -0
- package/node_modules/@sap/cds-compiler/CHANGELOG.md +83 -0
- package/node_modules/@sap/cds-compiler/bin/cdsse.js +1 -1
- package/node_modules/@sap/cds-compiler/doc/EffectiveCSN.md +3314 -0
- package/node_modules/@sap/cds-compiler/lib/api/main.js +9 -6
- package/node_modules/@sap/cds-compiler/lib/api/options.js +3 -3
- package/node_modules/@sap/cds-compiler/lib/{model → base}/csnUtils.js +5 -5
- package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +54 -6
- package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +4 -4
- package/node_modules/@sap/cds-compiler/lib/{model → base}/sortViews.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/assocOutsideService.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/checkForTypes.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/checkPathsInStoredCalcElement.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/elements.js +37 -3
- package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/existsInForbiddenPlaces.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/hasPersistedElements.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/manyExpand.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/manyNavigations.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/onConditions.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/parameters.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/queryNoDbArtifacts.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/selectItems.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/structuredAnnoExpressions.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/typeParameters.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/types.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/validator.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +20 -12
- package/node_modules/@sap/cds-compiler/lib/compiler/builtins.js +9 -4
- package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +50 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/define.js +303 -323
- package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +5 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +1015 -1177
- package/node_modules/@sap/cds-compiler/lib/compiler/generate.js +55 -42
- package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +74 -45
- package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +1 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +6 -4
- package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +30 -49
- package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +32 -18
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/edmJson.js +3 -3
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/genericTranslation.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/preprocessAnnotations.js +2 -3
- package/node_modules/@sap/cds-compiler/lib/edm/csn2edm.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edm.js +6 -7
- package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edmInboundChecks.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edmPreprocessor.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edmUtils.js +12 -7
- package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
- package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +15 -15
- package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +7 -0
- package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +30 -30
- package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +2 -1
- package/node_modules/@sap/cds-compiler/lib/main.js +4 -1
- package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +42 -15
- package/node_modules/@sap/cds-compiler/lib/render/DuplicateChecker.js +37 -11
- package/node_modules/@sap/cds-compiler/lib/render/manageConstraints.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +11 -6
- package/node_modules/@sap/cds-compiler/lib/render/toRename.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/render/toSql.js +74 -24
- package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +81 -0
- package/node_modules/@sap/cds-compiler/lib/render/utils/sql.js +17 -10
- package/node_modules/@sap/cds-compiler/lib/transform/db/assertUnique.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +3 -4
- package/node_modules/@sap/cds-compiler/lib/transform/db/assocsToQueries/transformExists.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/db/cdsPersistence.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +6 -5
- package/node_modules/@sap/cds-compiler/lib/transform/db/expansion.js +7 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/flattening.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/{modelCompare/compare.js → transform/db/migration/diffModels.js} +5 -5
- package/node_modules/@sap/cds-compiler/lib/{modelCompare/utils/filter.js → transform/db/migration/filterDiff.js} +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/db/processSqlServices.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/rewriteCalculatedElements.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/temporal.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/views.js +2 -6
- package/node_modules/@sap/cds-compiler/lib/transform/draft/db.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/draft/odata.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/associations.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/flattening.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +3 -2
- package/node_modules/@sap/cds-compiler/lib/transform/effective/misc.js +2 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/queries.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/types.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/forOdata.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +9 -4
- package/node_modules/@sap/cds-compiler/lib/transform/localized.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/odata/adaptAnnotationRefs.js +5 -11
- package/node_modules/@sap/cds-compiler/lib/transform/odata/createForeignKeys.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/odata/flattening.js +4 -4
- package/node_modules/@sap/cds-compiler/lib/transform/odata/foreignKeyRefsInXprAnnos.js +5 -3
- package/node_modules/@sap/cds-compiler/lib/transform/odata/toFinalBaseType.js +29 -5
- package/node_modules/@sap/cds-compiler/lib/transform/odata/typesExposure.js +13 -3
- package/node_modules/@sap/cds-compiler/lib/transform/odata/utils.js +9 -0
- package/node_modules/@sap/cds-compiler/lib/transform/transformUtils.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/tupleExpansion.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/coreComputed.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/universalCsnEnricher.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/utils.js +1 -1
- package/node_modules/@sap/cds-compiler/package.json +1 -1
- package/node_modules/@sap/cds-mtxs/CHANGELOG.md +55 -0
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +4 -6
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +5 -4
- package/node_modules/@sap/cds-mtxs/cds-plugin.js +38 -2
- package/node_modules/@sap/cds-mtxs/db/t0.cds +7 -0
- package/node_modules/@sap/cds-mtxs/lib/utils.js +129 -20
- package/node_modules/@sap/cds-mtxs/package.json +15 -14
- package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +13 -12
- package/node_modules/@sap/cds-mtxs/srv/cf/saas-provisioning-service.cds +1 -0
- package/node_modules/@sap/cds-mtxs/srv/cf/sms-provisioning-service.cds +1 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/compat/update.js +5 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/config.js +1 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/csv-allowlist.js +64 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +4 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/protected-namespace.js +67 -5
- package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +199 -19
- package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +39 -15
- package/node_modules/@sap/cds-mtxs/srv/plugins/common.js +33 -12
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +24 -6
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-ctnr-mgr.js +3 -1
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-native.js +752 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/serverless.js +17 -20
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr-v2.js +511 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr.js +11 -4
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/tms.js +8 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +58 -43
- package/node_modules/@sap/cds-mtxs/srv/worker/job-worker-pool.js +1 -1
- package/node_modules/@sap/cds-mtxs/srv/worker/job-worker.js +1 -1
- package/node_modules/body-parser/README.md +17 -13
- package/node_modules/body-parser/lib/read.js +74 -57
- package/node_modules/body-parser/lib/types/json.js +11 -11
- package/node_modules/body-parser/lib/types/urlencoded.js +5 -5
- package/node_modules/body-parser/lib/utils.js +0 -15
- package/node_modules/body-parser/package.json +7 -12
- package/node_modules/chownr/LICENSE.md +63 -0
- package/node_modules/chownr/README.md +3 -0
- package/node_modules/chownr/dist/commonjs/index.d.ts +3 -0
- package/node_modules/chownr/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/chownr/dist/commonjs/index.js +93 -0
- package/node_modules/chownr/dist/commonjs/index.js.map +1 -0
- package/node_modules/chownr/dist/commonjs/package.json +3 -0
- package/node_modules/chownr/dist/esm/index.d.ts +3 -0
- package/node_modules/chownr/dist/esm/index.d.ts.map +1 -0
- package/node_modules/chownr/dist/esm/index.js +85 -0
- package/node_modules/chownr/dist/esm/index.js.map +1 -0
- package/node_modules/chownr/dist/esm/package.json +3 -0
- package/node_modules/chownr/package.json +69 -0
- package/node_modules/content-disposition/README.md +105 -35
- package/node_modules/content-disposition/dist/index.d.ts +72 -0
- package/node_modules/content-disposition/dist/index.js +388 -0
- package/node_modules/content-disposition/dist/index.js.map +1 -0
- package/node_modules/content-disposition/package.json +31 -19
- package/node_modules/content-type/README.md +34 -57
- package/node_modules/content-type/package.json +35 -25
- package/node_modules/encodeurl/README.md +14 -0
- package/node_modules/encodeurl/index.js +5 -10
- package/node_modules/encodeurl/package.json +10 -6
- package/node_modules/express/Readme.md +15 -9
- package/node_modules/express/lib/application.js +2 -2
- package/node_modules/express/lib/request.js +32 -19
- package/node_modules/express/lib/response.js +27 -30
- package/node_modules/express/package.json +10 -10
- package/node_modules/handlebars/bin/handlebars +1 -1
- package/node_modules/handlebars/dist/amd/handlebars/base.js +2 -2
- package/node_modules/handlebars/dist/amd/handlebars/compiler/base.js +2 -59
- package/node_modules/handlebars/dist/amd/handlebars/compiler/code-gen.js +68 -5
- package/node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js +160 -19
- package/node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js +23 -7
- package/node_modules/handlebars/dist/amd/handlebars/compiler/node-types.js +12 -0
- package/node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js +26 -7
- package/node_modules/handlebars/dist/amd/handlebars/compiler/whitespace-control.js +9 -4
- package/node_modules/handlebars/dist/amd/handlebars/exception.js +8 -4
- package/node_modules/handlebars/dist/amd/handlebars/helpers/each.js +40 -14
- package/node_modules/handlebars/dist/amd/handlebars/internal/proto-access.js +21 -1
- package/node_modules/handlebars/dist/amd/handlebars/runtime.js +24 -4
- package/node_modules/handlebars/dist/amd/handlebars/utils.js +4 -3
- package/node_modules/handlebars/dist/amd/precompiler.js +13 -7
- package/node_modules/handlebars/dist/cjs/handlebars/base.js +2 -2
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/base.js +1 -60
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/code-gen.js +64 -4
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js +161 -18
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js +23 -7
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/node-types.js +10 -0
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js +29 -6
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/whitespace-control.js +9 -4
- package/node_modules/handlebars/dist/cjs/handlebars/exception.js +8 -4
- package/node_modules/handlebars/dist/cjs/handlebars/helpers/each.js +40 -14
- package/node_modules/handlebars/dist/cjs/handlebars/internal/proto-access.js +21 -1
- package/node_modules/handlebars/dist/cjs/handlebars/runtime.js +24 -4
- package/node_modules/handlebars/dist/cjs/handlebars/utils.js +4 -3
- package/node_modules/handlebars/dist/cjs/precompiler.js +14 -6
- package/node_modules/handlebars/dist/handlebars.amd.js +401 -130
- package/node_modules/handlebars/dist/handlebars.amd.min.js +4 -4
- package/node_modules/handlebars/dist/handlebars.js +396 -125
- package/node_modules/handlebars/dist/handlebars.min.js +4 -4
- package/node_modules/handlebars/dist/handlebars.runtime.amd.js +100 -29
- package/node_modules/handlebars/dist/handlebars.runtime.amd.min.js +2 -2
- package/node_modules/handlebars/dist/handlebars.runtime.js +94 -23
- package/node_modules/handlebars/dist/handlebars.runtime.min.js +2 -2
- package/node_modules/handlebars/lib/handlebars/base.js +1 -1
- package/node_modules/handlebars/lib/handlebars/compiler/base.js +0 -67
- package/node_modules/handlebars/lib/handlebars/compiler/code-gen.js +65 -11
- package/node_modules/handlebars/lib/handlebars/compiler/compiler.js +164 -23
- package/node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js +23 -7
- package/node_modules/handlebars/lib/handlebars/compiler/node-types.js +24 -0
- package/node_modules/handlebars/lib/handlebars/compiler/visitor.js +29 -5
- package/node_modules/handlebars/lib/handlebars/compiler/whitespace-control.js +16 -5
- package/node_modules/handlebars/lib/handlebars/exception.js +7 -3
- package/node_modules/handlebars/lib/handlebars/helpers/each.js +39 -16
- package/node_modules/handlebars/lib/handlebars/internal/proto-access.js +22 -0
- package/node_modules/handlebars/lib/handlebars/runtime.js +36 -4
- package/node_modules/handlebars/lib/handlebars/utils.js +3 -2
- package/node_modules/handlebars/lib/precompiler.js +14 -5
- package/node_modules/handlebars/package.json +2 -2
- package/node_modules/handlebars/release-notes.md +20 -1
- package/node_modules/handlebars/types/index.d.ts +8 -0
- package/node_modules/hdb/cfg/VERSION +1 -1
- package/node_modules/hdb/lib/Client.js +6 -2
- package/node_modules/hdb/lib/protocol/ClientInfo.js +28 -15
- package/node_modules/hdb/lib/protocol/Connection.js +30 -3
- package/node_modules/hdb/lib/protocol/Writer.js +2 -2
- package/node_modules/hdb/lib/protocol/common/ConnectOption.js +2 -0
- package/node_modules/hdb/lib/protocol/common/ConnectOptionFlagSet1.js +18 -0
- package/node_modules/hdb/lib/protocol/common/ConnectOptionType.js +2 -0
- package/node_modules/hdb/lib/protocol/common/Constants.js +1 -0
- package/node_modules/hdb/lib/protocol/common/MessageType.js +3 -2
- package/node_modules/hdb/lib/protocol/common/PartKind.js +2 -1
- package/node_modules/hdb/lib/protocol/common/index.js +1 -0
- package/node_modules/hdb/lib/protocol/data/TextList.js +25 -17
- package/node_modules/hdb/lib/protocol/data/index.js +1 -0
- package/node_modules/hdb/lib/protocol/part/ConnectOptions.js +7 -0
- package/node_modules/hdb/lib/protocol/request/index.js +7 -0
- package/node_modules/hdb/package.json +1 -2
- package/node_modules/livereload-js/.github/workflows/main.yml +4 -4
- package/node_modules/livereload-js/README.md +3 -3
- package/node_modules/livereload-js/dist/livereload.js +839 -2742
- package/node_modules/livereload-js/dist/livereload.min.js +1 -1
- package/node_modules/livereload-js/package.json +11 -11
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/README.md +825 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts +545 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/minipass/dist/commonjs/index.js +1038 -0
- package/node_modules/minipass/dist/commonjs/index.js.map +1 -0
- package/node_modules/minipass/dist/commonjs/package.json +3 -0
- package/node_modules/minipass/dist/esm/index.d.ts +545 -0
- package/node_modules/minipass/dist/esm/index.d.ts.map +1 -0
- package/node_modules/minipass/dist/esm/index.js +1020 -0
- package/node_modules/minipass/dist/esm/index.js.map +1 -0
- package/node_modules/minipass/dist/esm/package.json +3 -0
- package/node_modules/minipass/package.json +77 -0
- package/node_modules/minizlib/LICENSE +26 -0
- package/node_modules/minizlib/README.md +64 -0
- package/node_modules/minizlib/dist/commonjs/constants.d.ts +2 -0
- package/node_modules/minizlib/dist/commonjs/constants.d.ts.map +1 -0
- package/node_modules/minizlib/dist/commonjs/constants.js +123 -0
- package/node_modules/minizlib/dist/commonjs/constants.js.map +1 -0
- package/node_modules/minizlib/dist/commonjs/index.d.ts +99 -0
- package/node_modules/minizlib/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/minizlib/dist/commonjs/index.js +416 -0
- package/node_modules/minizlib/dist/commonjs/index.js.map +1 -0
- package/node_modules/minizlib/dist/commonjs/package.json +3 -0
- package/node_modules/minizlib/dist/esm/constants.d.ts +2 -0
- package/node_modules/minizlib/dist/esm/constants.d.ts.map +1 -0
- package/node_modules/minizlib/dist/esm/constants.js +117 -0
- package/node_modules/minizlib/dist/esm/constants.js.map +1 -0
- package/node_modules/minizlib/dist/esm/index.d.ts +99 -0
- package/node_modules/minizlib/dist/esm/index.d.ts.map +1 -0
- package/node_modules/minizlib/dist/esm/index.js +363 -0
- package/node_modules/minizlib/dist/esm/index.js.map +1 -0
- package/node_modules/minizlib/dist/esm/package.json +3 -0
- package/node_modules/minizlib/package.json +80 -0
- package/node_modules/on-finished/index.js +14 -2
- package/node_modules/on-finished/package.json +11 -7
- package/node_modules/qs/.editorconfig +1 -1
- package/node_modules/qs/.github/THREAT_MODEL.md +4 -2
- package/node_modules/qs/CHANGELOG.md +103 -14
- package/node_modules/qs/README.md +90 -9
- package/node_modules/qs/dist/qs.js +19 -19
- package/node_modules/qs/eslint.config.mjs +61 -50
- package/node_modules/qs/lib/formats.js +7 -2
- package/node_modules/qs/lib/parse.js +121 -12
- package/node_modules/qs/lib/stringify.js +9 -7
- package/node_modules/qs/lib/utils.js +158 -15
- package/node_modules/qs/package.json +8 -8
- package/node_modules/qs/test/parse.js +509 -2
- package/node_modules/qs/test/stringify.js +485 -33
- package/node_modules/qs/test/utils.js +245 -3
- package/node_modules/semver/classes/range.js +2 -2
- package/node_modules/semver/internal/constants.js +30 -0
- package/node_modules/semver/internal/trim-comparator-whitespace.js +438 -0
- package/node_modules/semver/package.json +1 -1
- package/node_modules/tar/LICENSE.md +55 -0
- package/node_modules/tar/README.md +1233 -0
- package/node_modules/tar/dist/commonjs/create.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/create.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/create.js +82 -0
- package/node_modules/tar/dist/commonjs/create.js.map +1 -0
- package/node_modules/tar/dist/commonjs/cwd-error.d.ts +8 -0
- package/node_modules/tar/dist/commonjs/cwd-error.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/cwd-error.js +18 -0
- package/node_modules/tar/dist/commonjs/cwd-error.js.map +1 -0
- package/node_modules/tar/dist/commonjs/extract.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/extract.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/extract.js +88 -0
- package/node_modules/tar/dist/commonjs/extract.js.map +1 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.js +32 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.js.map +1 -0
- package/node_modules/tar/dist/commonjs/header.d.ts +53 -0
- package/node_modules/tar/dist/commonjs/header.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/header.js +348 -0
- package/node_modules/tar/dist/commonjs/header.js.map +1 -0
- package/node_modules/tar/dist/commonjs/index.d.ts +20 -0
- package/node_modules/tar/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/index.js +64 -0
- package/node_modules/tar/dist/commonjs/index.js.map +1 -0
- package/node_modules/tar/dist/commonjs/index.min.js +4 -0
- package/node_modules/tar/dist/commonjs/index.min.js.map +7 -0
- package/node_modules/tar/dist/commonjs/large-numbers.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/large-numbers.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/large-numbers.js +99 -0
- package/node_modules/tar/dist/commonjs/large-numbers.js.map +1 -0
- package/node_modules/tar/dist/commonjs/list.d.ts +7 -0
- package/node_modules/tar/dist/commonjs/list.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/list.js +153 -0
- package/node_modules/tar/dist/commonjs/list.js.map +1 -0
- package/node_modules/tar/dist/commonjs/make-command.d.ts +49 -0
- package/node_modules/tar/dist/commonjs/make-command.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/make-command.js +52 -0
- package/node_modules/tar/dist/commonjs/make-command.js.map +1 -0
- package/node_modules/tar/dist/commonjs/mkdir.d.ts +25 -0
- package/node_modules/tar/dist/commonjs/mkdir.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/mkdir.js +187 -0
- package/node_modules/tar/dist/commonjs/mkdir.js.map +1 -0
- package/node_modules/tar/dist/commonjs/mode-fix.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/mode-fix.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/mode-fix.js +29 -0
- package/node_modules/tar/dist/commonjs/mode-fix.js.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.js +38 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.js.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.js +12 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.js.map +1 -0
- package/node_modules/tar/dist/commonjs/options.d.ts +604 -0
- package/node_modules/tar/dist/commonjs/options.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/options.js +66 -0
- package/node_modules/tar/dist/commonjs/options.js.map +1 -0
- package/node_modules/tar/dist/commonjs/pack.d.ts +105 -0
- package/node_modules/tar/dist/commonjs/pack.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/pack.js +544 -0
- package/node_modules/tar/dist/commonjs/pack.js.map +1 -0
- package/node_modules/tar/dist/commonjs/package.json +3 -0
- package/node_modules/tar/dist/commonjs/parse.d.ts +92 -0
- package/node_modules/tar/dist/commonjs/parse.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/parse.js +655 -0
- package/node_modules/tar/dist/commonjs/parse.js.map +1 -0
- package/node_modules/tar/dist/commonjs/path-reservations.d.ts +11 -0
- package/node_modules/tar/dist/commonjs/path-reservations.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/path-reservations.js +170 -0
- package/node_modules/tar/dist/commonjs/path-reservations.js.map +1 -0
- package/node_modules/tar/dist/commonjs/pax.d.ts +26 -0
- package/node_modules/tar/dist/commonjs/pax.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/pax.js +182 -0
- package/node_modules/tar/dist/commonjs/pax.js.map +1 -0
- package/node_modules/tar/dist/commonjs/process-umask.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/process-umask.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/process-umask.js +7 -0
- package/node_modules/tar/dist/commonjs/process-umask.js.map +1 -0
- package/node_modules/tar/dist/commonjs/read-entry.d.ts +36 -0
- package/node_modules/tar/dist/commonjs/read-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/read-entry.js +136 -0
- package/node_modules/tar/dist/commonjs/read-entry.js.map +1 -0
- package/node_modules/tar/dist/commonjs/replace.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/replace.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/replace.js +227 -0
- package/node_modules/tar/dist/commonjs/replace.js.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.js +29 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.js.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.js +18 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.js.map +1 -0
- package/node_modules/tar/dist/commonjs/symlink-error.d.ts +9 -0
- package/node_modules/tar/dist/commonjs/symlink-error.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/symlink-error.js +19 -0
- package/node_modules/tar/dist/commonjs/symlink-error.js.map +1 -0
- package/node_modules/tar/dist/commonjs/types.d.ts +16 -0
- package/node_modules/tar/dist/commonjs/types.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/types.js +70 -0
- package/node_modules/tar/dist/commonjs/types.js.map +1 -0
- package/node_modules/tar/dist/commonjs/unpack.d.ts +101 -0
- package/node_modules/tar/dist/commonjs/unpack.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/unpack.js +932 -0
- package/node_modules/tar/dist/commonjs/unpack.js.map +1 -0
- package/node_modules/tar/dist/commonjs/update.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/update.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/update.js +33 -0
- package/node_modules/tar/dist/commonjs/update.js.map +1 -0
- package/node_modules/tar/dist/commonjs/warn-method.d.ts +24 -0
- package/node_modules/tar/dist/commonjs/warn-method.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/warn-method.js +31 -0
- package/node_modules/tar/dist/commonjs/warn-method.js.map +1 -0
- package/node_modules/tar/dist/commonjs/winchars.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/winchars.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/winchars.js +14 -0
- package/node_modules/tar/dist/commonjs/winchars.js.map +1 -0
- package/node_modules/tar/dist/commonjs/write-entry.d.ts +129 -0
- package/node_modules/tar/dist/commonjs/write-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/write-entry.js +698 -0
- package/node_modules/tar/dist/commonjs/write-entry.js.map +1 -0
- package/node_modules/tar/dist/esm/create.d.ts +3 -0
- package/node_modules/tar/dist/esm/create.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/create.js +76 -0
- package/node_modules/tar/dist/esm/create.js.map +1 -0
- package/node_modules/tar/dist/esm/cwd-error.d.ts +8 -0
- package/node_modules/tar/dist/esm/cwd-error.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/cwd-error.js +14 -0
- package/node_modules/tar/dist/esm/cwd-error.js.map +1 -0
- package/node_modules/tar/dist/esm/extract.d.ts +3 -0
- package/node_modules/tar/dist/esm/extract.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/extract.js +49 -0
- package/node_modules/tar/dist/esm/extract.js.map +1 -0
- package/node_modules/tar/dist/esm/get-write-flag.d.ts +2 -0
- package/node_modules/tar/dist/esm/get-write-flag.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/get-write-flag.js +26 -0
- package/node_modules/tar/dist/esm/get-write-flag.js.map +1 -0
- package/node_modules/tar/dist/esm/header.d.ts +53 -0
- package/node_modules/tar/dist/esm/header.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/header.js +311 -0
- package/node_modules/tar/dist/esm/header.js.map +1 -0
- package/node_modules/tar/dist/esm/index.d.ts +20 -0
- package/node_modules/tar/dist/esm/index.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/index.js +20 -0
- package/node_modules/tar/dist/esm/index.js.map +1 -0
- package/node_modules/tar/dist/esm/index.min.js +4 -0
- package/node_modules/tar/dist/esm/index.min.js.map +7 -0
- package/node_modules/tar/dist/esm/large-numbers.d.ts +3 -0
- package/node_modules/tar/dist/esm/large-numbers.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/large-numbers.js +94 -0
- package/node_modules/tar/dist/esm/large-numbers.js.map +1 -0
- package/node_modules/tar/dist/esm/list.d.ts +7 -0
- package/node_modules/tar/dist/esm/list.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/list.js +113 -0
- package/node_modules/tar/dist/esm/list.js.map +1 -0
- package/node_modules/tar/dist/esm/make-command.d.ts +49 -0
- package/node_modules/tar/dist/esm/make-command.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/make-command.js +48 -0
- package/node_modules/tar/dist/esm/make-command.js.map +1 -0
- package/node_modules/tar/dist/esm/mkdir.d.ts +25 -0
- package/node_modules/tar/dist/esm/mkdir.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/mkdir.js +179 -0
- package/node_modules/tar/dist/esm/mkdir.js.map +1 -0
- package/node_modules/tar/dist/esm/mode-fix.d.ts +2 -0
- package/node_modules/tar/dist/esm/mode-fix.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/mode-fix.js +25 -0
- package/node_modules/tar/dist/esm/mode-fix.js.map +1 -0
- package/node_modules/tar/dist/esm/normalize-unicode.d.ts +2 -0
- package/node_modules/tar/dist/esm/normalize-unicode.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/normalize-unicode.js +34 -0
- package/node_modules/tar/dist/esm/normalize-unicode.js.map +1 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.d.ts +2 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.js +9 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.js.map +1 -0
- package/node_modules/tar/dist/esm/options.d.ts +604 -0
- package/node_modules/tar/dist/esm/options.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/options.js +54 -0
- package/node_modules/tar/dist/esm/options.js.map +1 -0
- package/node_modules/tar/dist/esm/pack.d.ts +105 -0
- package/node_modules/tar/dist/esm/pack.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/pack.js +502 -0
- package/node_modules/tar/dist/esm/pack.js.map +1 -0
- package/node_modules/tar/dist/esm/package.json +3 -0
- package/node_modules/tar/dist/esm/parse.d.ts +92 -0
- package/node_modules/tar/dist/esm/parse.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/parse.js +651 -0
- package/node_modules/tar/dist/esm/parse.js.map +1 -0
- package/node_modules/tar/dist/esm/path-reservations.d.ts +11 -0
- package/node_modules/tar/dist/esm/path-reservations.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/path-reservations.js +166 -0
- package/node_modules/tar/dist/esm/path-reservations.js.map +1 -0
- package/node_modules/tar/dist/esm/pax.d.ts +26 -0
- package/node_modules/tar/dist/esm/pax.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/pax.js +178 -0
- package/node_modules/tar/dist/esm/pax.js.map +1 -0
- package/node_modules/tar/dist/esm/process-umask.d.ts +2 -0
- package/node_modules/tar/dist/esm/process-umask.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/process-umask.js +3 -0
- package/node_modules/tar/dist/esm/process-umask.js.map +1 -0
- package/node_modules/tar/dist/esm/read-entry.d.ts +36 -0
- package/node_modules/tar/dist/esm/read-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/read-entry.js +132 -0
- package/node_modules/tar/dist/esm/read-entry.js.map +1 -0
- package/node_modules/tar/dist/esm/replace.d.ts +2 -0
- package/node_modules/tar/dist/esm/replace.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/replace.js +221 -0
- package/node_modules/tar/dist/esm/replace.js.map +1 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.d.ts +2 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.js +25 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.js.map +1 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.d.ts +2 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.js +14 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.js.map +1 -0
- package/node_modules/tar/dist/esm/symlink-error.d.ts +9 -0
- package/node_modules/tar/dist/esm/symlink-error.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/symlink-error.js +15 -0
- package/node_modules/tar/dist/esm/symlink-error.js.map +1 -0
- package/node_modules/tar/dist/esm/types.d.ts +16 -0
- package/node_modules/tar/dist/esm/types.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/types.js +65 -0
- package/node_modules/tar/dist/esm/types.js.map +1 -0
- package/node_modules/tar/dist/esm/unpack.d.ts +101 -0
- package/node_modules/tar/dist/esm/unpack.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/unpack.js +891 -0
- package/node_modules/tar/dist/esm/unpack.js.map +1 -0
- package/node_modules/tar/dist/esm/update.d.ts +2 -0
- package/node_modules/tar/dist/esm/update.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/update.js +30 -0
- package/node_modules/tar/dist/esm/update.js.map +1 -0
- package/node_modules/tar/dist/esm/warn-method.d.ts +24 -0
- package/node_modules/tar/dist/esm/warn-method.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/warn-method.js +27 -0
- package/node_modules/tar/dist/esm/warn-method.js.map +1 -0
- package/node_modules/tar/dist/esm/winchars.d.ts +3 -0
- package/node_modules/tar/dist/esm/winchars.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/winchars.js +9 -0
- package/node_modules/tar/dist/esm/winchars.js.map +1 -0
- package/node_modules/tar/dist/esm/write-entry.d.ts +129 -0
- package/node_modules/tar/dist/esm/write-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/write-entry.js +656 -0
- package/node_modules/tar/dist/esm/write-entry.js.map +1 -0
- package/node_modules/tar/package.json +298 -0
- package/node_modules/ws/README.md +21 -29
- package/node_modules/ws/lib/buffer-util.js +13 -2
- package/node_modules/ws/lib/sender.js +4 -1
- package/node_modules/ws/lib/websocket.js +25 -6
- package/node_modules/ws/package.json +1 -1
- package/node_modules/yallist/LICENSE.md +63 -0
- package/node_modules/yallist/README.md +205 -0
- package/node_modules/yallist/dist/commonjs/index.d.ts +39 -0
- package/node_modules/yallist/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/yallist/dist/commonjs/index.js +384 -0
- package/node_modules/yallist/dist/commonjs/index.js.map +1 -0
- package/node_modules/yallist/dist/commonjs/package.json +3 -0
- package/node_modules/yallist/dist/esm/index.d.ts +39 -0
- package/node_modules/yallist/dist/esm/index.d.ts.map +1 -0
- package/node_modules/yallist/dist/esm/index.js +379 -0
- package/node_modules/yallist/dist/esm/index.js.map +1 -0
- package/node_modules/yallist/dist/esm/package.json +3 -0
- package/node_modules/yallist/package.json +68 -0
- package/package.json +7 -1
- package/bin/completion/templates/cds-tmpl.fish +0 -65
- package/bin/completion/templates/cds-tmpl.ps1 +0 -217
- package/bin/completion/templates/cds-tmpl.sh +0 -93
- package/bin/completion/templates/cds-tmpl.zsh +0 -74
- package/node_modules/@cap-js/db-service/lib/recursion-guard.js +0 -40
- package/node_modules/@sap/cds/lib/env/cds-requires.js +0 -327
- package/node_modules/@sap/cds-mtxs/srv/bootstrap.cds +0 -2
- package/node_modules/@sap/cds-mtxs/srv/bootstrap.js +0 -33
- package/node_modules/body-parser/node_modules/content-type/LICENSE +0 -22
- package/node_modules/body-parser/node_modules/content-type/README.md +0 -71
- package/node_modules/body-parser/node_modules/content-type/package.json +0 -52
- package/node_modules/content-disposition/index.js +0 -536
- package/node_modules/content-type/HISTORY.md +0 -29
- package/node_modules/content-type/index.js +0 -225
- package/node_modules/negotiator/node_modules/content-type/LICENSE +0 -22
- package/node_modules/negotiator/node_modules/content-type/README.md +0 -71
- package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +0 -46
- package/node_modules/negotiator/node_modules/content-type/dist/index.js +0 -176
- package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +0 -1
- package/node_modules/negotiator/node_modules/content-type/package.json +0 -52
- package/node_modules/on-finished/HISTORY.md +0 -98
- package/node_modules/type-is/node_modules/content-type/LICENSE +0 -22
- package/node_modules/type-is/node_modules/content-type/README.md +0 -71
- package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +0 -46
- package/node_modules/type-is/node_modules/content-type/dist/index.js +0 -176
- package/node_modules/type-is/node_modules/content-type/dist/index.js.map +0 -1
- package/node_modules/type-is/node_modules/content-type/package.json +0 -52
- /package/lib/init/template/vue/files/src/{main.js → main.{{extension}}.hbs} +0 -0
- /package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/utilities.js +0 -0
- /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.d.ts +0 -0
- /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.js +0 -0
- /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.js.map +0 -0
|
@@ -0,0 +1,3314 @@
|
|
|
1
|
+
# Effective CSN
|
|
2
|
+
|
|
3
|
+
> **Status:** feature - implemented, up-to-date, Sep 2026
|
|
4
|
+
|
|
5
|
+
<!-- toc: start -->
|
|
6
|
+
|
|
7
|
+
1. [Introduction](#introduction)
|
|
8
|
+
2. [How to obtain Effective CSN](#how-to-obtain-effective-csn)
|
|
9
|
+
1. [Via compiler CLI (`cdsc`)](#via-compiler-cli-cdsc)
|
|
10
|
+
2. [Via compiler API](#via-compiler-api)
|
|
11
|
+
3. [Options](#options)
|
|
12
|
+
4. [Starting point: "Inferred CSN"](#starting-point-inferred-csn)
|
|
13
|
+
1. [Full and complete model](#full-and-complete-model)
|
|
14
|
+
2. [Extensions and Includes are applied](#extensions-and-includes-are-applied)
|
|
15
|
+
3. [Composition of aspect is unfolded](#composition-of-aspect-is-unfolded)
|
|
16
|
+
4. [Annotations are propagated](#annotations-are-propagated)
|
|
17
|
+
5. [Inferred elements are computed for views and projections](#inferred-elements-are-computed-for-views-and-projections)
|
|
18
|
+
6. [Localized elements are unfolded](#localized-elements-are-unfolded)
|
|
19
|
+
7. [Effective CSN feature/flavor "Service Exposure Rendering"](#effective-csn-featureflavor-service-exposure-rendering)
|
|
20
|
+
5. [Further transformations](#further-transformations)
|
|
21
|
+
1. [Upper/lower case](#upperlower-case)
|
|
22
|
+
2. [Stay with CDS type system](#stay-with-cds-type-system)
|
|
23
|
+
3. [Resolve simple types](#resolve-simple-types)
|
|
24
|
+
4. [Flatten structured types](#flatten-structured-types)
|
|
25
|
+
5. [Resolve Managed Associations](#resolve-managed-associations)
|
|
26
|
+
6. [Keep array types (many)](#keep-array-types-many)
|
|
27
|
+
7. [Cleanup: remove no longer needed objects and attributes](#cleanup-remove-no-longer-needed-objects-and-attributes)
|
|
28
|
+
8. [Virtual elements](#virtual-elements)
|
|
29
|
+
9. [Enums](#enums)
|
|
30
|
+
10. [Session variables](#session-variables)
|
|
31
|
+
11. [Actions and Functions](#actions-and-functions)
|
|
32
|
+
12. [Associations via backlink](#associations-via-backlink)
|
|
33
|
+
13. [Calculated Elements](#calculated-elements)
|
|
34
|
+
14. [$calc](#calc)
|
|
35
|
+
15. [Draft](#draft)
|
|
36
|
+
16. [Queries](#queries)
|
|
37
|
+
17. [Query: No assoc2join](#query-no-assoc2join)
|
|
38
|
+
18. [Query: EXISTS paths](#query-exists-paths)
|
|
39
|
+
19. [Query: CDL style cast](#query-cdl-style-cast)
|
|
40
|
+
20. [Query: $projection](#query-projection)
|
|
41
|
+
21. [Query: select *](#query-select-)
|
|
42
|
+
22. [Query: filter](#query-filter)
|
|
43
|
+
23. [Query: expand and inline](#query-expand-and-inline)
|
|
44
|
+
24. [Query: path in FROM](#query-path-in-from)
|
|
45
|
+
25. [Query: path in WHERE, GROUP BY](#query-path-in-where-group-by)
|
|
46
|
+
26. [Query: Projection vs View](#query-projection-vs-view)
|
|
47
|
+
27. [Query: Mixin associations](#query-mixin-associations)
|
|
48
|
+
28. [Query: Redirect](#query-redirect)
|
|
49
|
+
29. [Query: Defining associations in the select list](#query-defining-associations-in-the-select-list)
|
|
50
|
+
30. [Query: Exposing associations](#query-exposing-associations)
|
|
51
|
+
31. [Annotations](#annotations)
|
|
52
|
+
32. [Localized metadata](#localized-metadata)
|
|
53
|
+
33. [Reduce to one service](#reduce-to-one-service)
|
|
54
|
+
|
|
55
|
+
<!-- toc: end -->
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Introduction
|
|
60
|
+
|
|
61
|
+
This document describes "Effective CSN", i.e. the CSN produced by the `for.effective` compiler function.
|
|
62
|
+
|
|
63
|
+
The term "Effective CSN" means that this CSN is designed for consumption. It is __not__ intended for further
|
|
64
|
+
modelling, and it is also not intended to be extended, as everything is already expanded/unfolded/computed/...
|
|
65
|
+
|
|
66
|
+
The main purpose is to produce a CSN that can be consumed by parties outside of CAP by transforming
|
|
67
|
+
CAP-specific features (for example, managed associations) into generally understood representations.
|
|
68
|
+
|
|
69
|
+
Effective CSN is produced by starting with the core compiler CSN ("Inferred CSN" or "Client CSN")
|
|
70
|
+
and then applying additional transformations, which are described in detail below.
|
|
71
|
+
|
|
72
|
+
This document only describes enumerable properties of Effective CSN. If you look directly
|
|
73
|
+
at the JSON object as it is returned from the respective compiler function, there may
|
|
74
|
+
also be additional non-enumerable properties. These non-enumerable properties are not
|
|
75
|
+
part of the stable, documented API and may change at any time.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## How to obtain Effective CSN
|
|
79
|
+
|
|
80
|
+
### Via compiler CLI (`cdsc`)
|
|
81
|
+
|
|
82
|
+
After installing `@sap/cds-compiler` (see the README for install instructions), the `cdsc` binary
|
|
83
|
+
is available on the PATH. Use the `forEffective` command:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
cdsc forEffective <file.cds>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Options can be passed as `--<optionName>` flags, e.g.:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
cdsc forEffective --resolveProjections <file.cds>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Run `cdsc --help` for a full list of commands and flags.
|
|
96
|
+
|
|
97
|
+
### Via compiler API
|
|
98
|
+
|
|
99
|
+
The function is exposed as `for.effective` on the compiler API:
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
const cds = require('@sap/cds-compiler');
|
|
103
|
+
|
|
104
|
+
const inferredCsn = cds.compileSync(['<file.cds>'], dir, {});
|
|
105
|
+
const effectiveCsn = cds.for.effective(inferredCsn, options);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`inferredCsn` is a CSN object (e.g. the result of `cds.compileSync(...)`) and
|
|
109
|
+
`options` is an optional object with any of the supported option keys (see [Options](#options) below).
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## Options
|
|
113
|
+
|
|
114
|
+
The following options are supported by `for.effective`:
|
|
115
|
+
|
|
116
|
+
| Option | Description |
|
|
117
|
+
|-------------------------|-------------|
|
|
118
|
+
| `resolveSimpleTypes` | experimental, see section [Resolve simple types](#resolve-simple-types) |
|
|
119
|
+
| `resolveProjections` | see section [Query: Projection vs View](#query-projection-vs-view) |
|
|
120
|
+
| `keepLocalized` | see section [Localized elements are unfolded](#localized-elements-are-unfolded) |
|
|
121
|
+
| `effectiveServiceName` | see section [Reduce to one service](#reduce-to-one-service) |
|
|
122
|
+
| `stringifyAnnoXpr` | see section [Annotations](#annotations) |
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
## Starting point: "Inferred CSN"
|
|
126
|
+
|
|
127
|
+
The CSN generated by the CDS compiler ("Inferred CSN" or "client CSN") already has the
|
|
128
|
+
features/flavors described in the following sections.
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
### Full and complete model
|
|
132
|
+
|
|
133
|
+
The Inferred CSN contains the full model. There are no dangling references.
|
|
134
|
+
|
|
135
|
+
Note: `cds build` compiles CDS files from the _db_, _srv_, and _app_ folders.
|
|
136
|
+
Thus also annotations (e.g. labels) from the _app_ folder get into the Effective CSN.
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
### Extensions and Includes are applied
|
|
140
|
+
|
|
141
|
+
All extends, annotates, and includes are applied.
|
|
142
|
+
|
|
143
|
+
Inferred CSN still contains
|
|
144
|
+
* named aspects
|
|
145
|
+
* annotates that cannot be applied
|
|
146
|
+
|
|
147
|
+
For Effective CSN, a cleanup is done (see section [Cleanup](#cleanup-remove-no-longer-needed-objects-and-attributes)),
|
|
148
|
+
where for example aspects and unapplied annotations are removed.
|
|
149
|
+
|
|
150
|
+
Example:
|
|
151
|
+
CDS:
|
|
152
|
+
```cds
|
|
153
|
+
aspect A { x : Integer; };
|
|
154
|
+
entity E : A {}
|
|
155
|
+
extend E with { y : Integer; }
|
|
156
|
+
annotate E:x with @Foo;
|
|
157
|
+
annotate E:miss with @Foo;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
<details>
|
|
161
|
+
<summary>Inferred CSN</summary>
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"definitions": {
|
|
166
|
+
"A": {
|
|
167
|
+
"kind": "aspect",
|
|
168
|
+
"elements": {
|
|
169
|
+
"x": { "type": "cds.Integer" }
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"E": {
|
|
173
|
+
"kind": "entity",
|
|
174
|
+
"includes": ["A"],
|
|
175
|
+
"elements": {
|
|
176
|
+
"x": {"@Foo": true,
|
|
177
|
+
"type": "cds.Integer"},
|
|
178
|
+
"y": {"type": "cds.Integer"}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"extensions": [
|
|
183
|
+
{
|
|
184
|
+
"annotate": "E",
|
|
185
|
+
"elements": {
|
|
186
|
+
"miss": { "@Foo": true }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
</details>
|
|
194
|
+
|
|
195
|
+
<details>
|
|
196
|
+
<summary>Effective CSN</summary>
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"definitions": {
|
|
201
|
+
"E": {
|
|
202
|
+
"kind": "entity",
|
|
203
|
+
"elements": {
|
|
204
|
+
"x": {"@Foo": true,
|
|
205
|
+
"type": "cds.Integer"},
|
|
206
|
+
"y": {"type": "cds.Integer"}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
</details>
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
### Composition of aspect is unfolded
|
|
216
|
+
|
|
217
|
+
All "composition of aspect" are unfolded, i.e. respective child entities are generated
|
|
218
|
+
and linked to the parent entity via a managed `up_` association.
|
|
219
|
+
|
|
220
|
+
For Effective CSN, in a later step [Resolve Managed Associations](#resolve-managed-associations)
|
|
221
|
+
the managed associations are converted to unmanaged ones and `targetAspect` properties
|
|
222
|
+
are removed during [Cleanup](#cleanup-remove-no-longer-needed-objects-and-attributes).
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
Example:
|
|
226
|
+
CDS:
|
|
227
|
+
```cds
|
|
228
|
+
aspect A { x : Integer; };
|
|
229
|
+
|
|
230
|
+
entity E {
|
|
231
|
+
key id : Integer;
|
|
232
|
+
c1 : Composition of many A; // named aspect
|
|
233
|
+
c2 : Composition of many { x : Integer; } // anonymous aspect
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
<details>
|
|
238
|
+
<summary>Inferred CSN</summary>
|
|
239
|
+
|
|
240
|
+
```jsonc
|
|
241
|
+
{
|
|
242
|
+
"definitions": {
|
|
243
|
+
"A": {
|
|
244
|
+
"kind": "aspect",
|
|
245
|
+
"elements": {
|
|
246
|
+
"x": { "type": "cds.Integer" }
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
"E": {
|
|
250
|
+
"kind": "entity",
|
|
251
|
+
"elements": {
|
|
252
|
+
"id": {"key": true, "type": "cds.Integer"},
|
|
253
|
+
"c1": {
|
|
254
|
+
"type": "cds.Composition",
|
|
255
|
+
"cardinality": { "max": "*" },
|
|
256
|
+
"targetAspect": "A",
|
|
257
|
+
"target": "E.c1",
|
|
258
|
+
"on": [{"ref": ["c1","up_"]}, "=", {"ref": ["$self"]}]
|
|
259
|
+
},
|
|
260
|
+
"c2": {
|
|
261
|
+
"type": "cds.Composition",
|
|
262
|
+
"cardinality": { "max": "*" },
|
|
263
|
+
"targetAspect": {
|
|
264
|
+
"elements": {
|
|
265
|
+
"x": { "type": "cds.Integer" }
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
"target": "E.c2",
|
|
269
|
+
"on": [{"ref": ["c2","up_"]}, "=", {"ref": ["$self"]}]
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"E.c1": {
|
|
274
|
+
"kind": "entity",
|
|
275
|
+
"elements": {
|
|
276
|
+
"up_": {
|
|
277
|
+
"key": true,
|
|
278
|
+
"type": "cds.Association",
|
|
279
|
+
"cardinality": { "min": 1, "max": 1 },
|
|
280
|
+
"target": "E",
|
|
281
|
+
"keys": [{"ref": ["id"]}],
|
|
282
|
+
"notNull": true
|
|
283
|
+
},
|
|
284
|
+
"x": {"type": "cds.Integer"}
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
"E.c2": {
|
|
288
|
+
/* like E.c1 */
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
</details>
|
|
295
|
+
|
|
296
|
+
<details>
|
|
297
|
+
<summary>Effective CSN</summary>
|
|
298
|
+
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"definitions": {
|
|
302
|
+
"E": {
|
|
303
|
+
"kind": "entity",
|
|
304
|
+
"elements": {
|
|
305
|
+
"id": {"key": true, "type": "cds.Integer"},
|
|
306
|
+
"c1": {
|
|
307
|
+
"type": "cds.Composition",
|
|
308
|
+
"cardinality": {"max": "*"},
|
|
309
|
+
"target": "E.c1",
|
|
310
|
+
"on": [{"ref": ["c1","up_"]},"=",{"ref": ["$self"]}]
|
|
311
|
+
},
|
|
312
|
+
"c2": {
|
|
313
|
+
"type": "cds.Composition",
|
|
314
|
+
"cardinality": {"max": "*"},
|
|
315
|
+
"target": "E.c2",
|
|
316
|
+
"on": [{"ref": ["c2","up_"]},"=",{"ref": ["$self"]}]
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
"E.c1": {
|
|
321
|
+
"kind": "entity",
|
|
322
|
+
"elements": {
|
|
323
|
+
"up_": {
|
|
324
|
+
"type": "cds.Association",
|
|
325
|
+
"cardinality": {"min": 1,"max": 1},
|
|
326
|
+
"target": "E",
|
|
327
|
+
"on": [{"ref": ["up_","id"]},"=",{"ref": ["up__id"]}]
|
|
328
|
+
},
|
|
329
|
+
"up__id": {
|
|
330
|
+
"type": "cds.Integer",
|
|
331
|
+
"notNull": true,
|
|
332
|
+
"key": true
|
|
333
|
+
},
|
|
334
|
+
"x": {"type": "cds.Integer"}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
"E.c2": {
|
|
338
|
+
/* like E.c1 */
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
</details>
|
|
345
|
+
|
|
346
|
+
<details>
|
|
347
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
348
|
+
|
|
349
|
+
```cds
|
|
350
|
+
entity E {
|
|
351
|
+
key id: Integer;
|
|
352
|
+
c1 : Composition of many E.c1 on c1.up_ = $self;
|
|
353
|
+
c2 : Composition of many E.c2 on c2.up_ = $self;
|
|
354
|
+
}
|
|
355
|
+
entity E.c1 {
|
|
356
|
+
up_: Association to one E on up_.id = up__id;
|
|
357
|
+
key up__id : Integer;
|
|
358
|
+
x : Integer;
|
|
359
|
+
}
|
|
360
|
+
entity E.c2 {
|
|
361
|
+
up_: Association to one E on up_.id = up__id;
|
|
362
|
+
key up__id : Integer;
|
|
363
|
+
x : Integer;
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
</details>
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
### Annotations are propagated
|
|
370
|
+
|
|
371
|
+
All annotations are explicitly inherited/propagated along type chains, views/projections, and includes.
|
|
372
|
+
|
|
373
|
+
Example:
|
|
374
|
+
CDS:
|
|
375
|
+
```cds
|
|
376
|
+
@Foo
|
|
377
|
+
type T : Integer;
|
|
378
|
+
|
|
379
|
+
@FromAspect
|
|
380
|
+
aspect A {};
|
|
381
|
+
|
|
382
|
+
entity E {
|
|
383
|
+
@Bar
|
|
384
|
+
a : T;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
entity P as select from E { a };
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
<details>
|
|
391
|
+
<summary>Inferred CSN</summary>
|
|
392
|
+
|
|
393
|
+
```json
|
|
394
|
+
{
|
|
395
|
+
"definitions": {
|
|
396
|
+
"T": {
|
|
397
|
+
"kind": "type",
|
|
398
|
+
"@Foo": true,
|
|
399
|
+
"type": "cds.Integer"
|
|
400
|
+
},
|
|
401
|
+
"A": {
|
|
402
|
+
"kind": "aspect",
|
|
403
|
+
"@FromAspect": true,
|
|
404
|
+
"elements": {}
|
|
405
|
+
},
|
|
406
|
+
"E": {
|
|
407
|
+
"kind": "entity",
|
|
408
|
+
"@FromAspect": true,
|
|
409
|
+
"includes": [
|
|
410
|
+
"A"
|
|
411
|
+
],
|
|
412
|
+
"elements": {
|
|
413
|
+
"a": {"@Bar": true, "@Foo": true, "type": "T"}
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
"P": {
|
|
417
|
+
"kind": "entity",
|
|
418
|
+
"@FromAspect": true,
|
|
419
|
+
"query": {
|
|
420
|
+
"SELECT": {
|
|
421
|
+
"from": {"ref": ["E"]},
|
|
422
|
+
"columns": [
|
|
423
|
+
{"ref": ["a"]}
|
|
424
|
+
]
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
"elements": {
|
|
428
|
+
"a": {"@Bar": true, "@Foo": true, "type": "T"}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
</details>
|
|
436
|
+
|
|
437
|
+
<details>
|
|
438
|
+
<summary>Effective CSN</summary>
|
|
439
|
+
|
|
440
|
+
Here [types are already resolved](#resolve-simple-types).
|
|
441
|
+
```json
|
|
442
|
+
{
|
|
443
|
+
"definitions": {
|
|
444
|
+
"E": {
|
|
445
|
+
"kind": "entity",
|
|
446
|
+
"@FromAspect": true,
|
|
447
|
+
"elements": {
|
|
448
|
+
"a": {"@Bar": true, "@Foo": true, "type": "cds.Integer"}
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
"P": {
|
|
452
|
+
"kind": "entity",
|
|
453
|
+
"@FromAspect": true,
|
|
454
|
+
"query": {
|
|
455
|
+
"SELECT": {
|
|
456
|
+
"from": {"ref": ["E"]},
|
|
457
|
+
"columns": [
|
|
458
|
+
{"ref": ["a"]}
|
|
459
|
+
]
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
"elements": {
|
|
463
|
+
"a": {"@Bar": true, "@Foo": true, "type": "cds.Integer"}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
</details>
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
### Inferred elements are computed for views and projections
|
|
473
|
+
|
|
474
|
+
Inferred elements are computed for views and projections. They are not computed
|
|
475
|
+
for the single queries inside the view/projection.
|
|
476
|
+
|
|
477
|
+
Example: see other examples with views/projections.
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
### Localized elements are unfolded
|
|
481
|
+
|
|
482
|
+
For localized elements, the corresponding text entity and associations are generated.
|
|
483
|
+
|
|
484
|
+
Example:
|
|
485
|
+
CDS:
|
|
486
|
+
```cds
|
|
487
|
+
entity E {
|
|
488
|
+
key id : Integer;
|
|
489
|
+
t1 : localized String;
|
|
490
|
+
t2 : localized String;
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
<details>
|
|
494
|
+
<summary>Inferred CSN</summary>
|
|
495
|
+
|
|
496
|
+
```json
|
|
497
|
+
{
|
|
498
|
+
"definitions": {
|
|
499
|
+
"E": {
|
|
500
|
+
"kind": "entity",
|
|
501
|
+
"elements": {
|
|
502
|
+
"id": {"key": true,"type": "cds.Integer" },
|
|
503
|
+
"t1": {"localized": true,"type": "cds.String"},
|
|
504
|
+
"t2": {"localized": true,"type": "cds.String"},
|
|
505
|
+
"texts": {
|
|
506
|
+
"type": "cds.Composition",
|
|
507
|
+
"cardinality": {"max": "*"},
|
|
508
|
+
"target": "E.texts",
|
|
509
|
+
"on": [{"ref": ["texts","id"]},"=",{"ref": ["id"]}]
|
|
510
|
+
},
|
|
511
|
+
"localized": {
|
|
512
|
+
"type": "cds.Association",
|
|
513
|
+
"target": "E.texts",
|
|
514
|
+
"on": [
|
|
515
|
+
{"ref": ["localized","id"]}, "=", {"ref": ["id"]},
|
|
516
|
+
"and",
|
|
517
|
+
{"ref": ["localized","locale"]}, "=", {"ref": ["$user","locale"]}
|
|
518
|
+
]
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
"E.texts": {
|
|
523
|
+
"kind": "entity",
|
|
524
|
+
"elements": {
|
|
525
|
+
"locale": {"key": true,"type": "cds.String","length": 14},
|
|
526
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
527
|
+
"t1": {"localized": null,"type": "cds.String"},
|
|
528
|
+
"t2": {"localized": null,"type": "cds.String"}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
</details>
|
|
536
|
+
|
|
537
|
+
By default, in Effective CSN the property `localized` is removed.
|
|
538
|
+
|
|
539
|
+
<details>
|
|
540
|
+
<summary>Effective CSN </summary>
|
|
541
|
+
|
|
542
|
+
Effective CSN looks like Inferred CSN, except that
|
|
543
|
+
* property `localized: true` is removed from `E:t1` and `E:t2`.
|
|
544
|
+
* property `localized: null` is removed from `E:texts.t1` and `E:texts.t2`.
|
|
545
|
+
</details>
|
|
546
|
+
|
|
547
|
+
<details>
|
|
548
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
549
|
+
|
|
550
|
+
```cds
|
|
551
|
+
entity E {
|
|
552
|
+
key id : Integer;
|
|
553
|
+
t1 : String;
|
|
554
|
+
t2 : String;
|
|
555
|
+
texts : Composition of many E.texts on texts.id = id;
|
|
556
|
+
localized : Association to one E.texts on localized.id = id and localized.locale = $user.locale;
|
|
557
|
+
}
|
|
558
|
+
entity E.texts {
|
|
559
|
+
key locale : String(14);
|
|
560
|
+
key id : Integer;
|
|
561
|
+
t1 : String;
|
|
562
|
+
t2 : String;
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
</details>
|
|
567
|
+
|
|
568
|
+
When option `keepLocalized` is set to `true` (default is `false`),
|
|
569
|
+
the property `localized` is kept and there is no difference between Inferred CSN and Effective CSN.
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
<br />
|
|
573
|
+
|
|
574
|
+
#### Unsolved problem: Localized data in effective CSN
|
|
575
|
+
|
|
576
|
+
Above the layer of base entities, where we have associations `texts` and `localized`,
|
|
577
|
+
the model (CSN) usually contains no information about how to obtain the translations
|
|
578
|
+
for a given localized element:
|
|
579
|
+
* Associations `texts` and `localized` are not propagated automatically. If wanted,
|
|
580
|
+
users have to explicitly propagate them through the view stack.
|
|
581
|
+
* If a view selects localized elements from two or more data sources, there is no
|
|
582
|
+
canonic `localized` or `texts` association any more that points to
|
|
583
|
+
the respective localized texts.
|
|
584
|
+
* If a calculated field contains localized data, it effectively is also depending
|
|
585
|
+
on the locale, but there is no model info about how to get the corresponding translations.
|
|
586
|
+
|
|
587
|
+
CAP today generates localized convenience views in the SQL persistence.
|
|
588
|
+
They implicitly contain the knowledge about how to get translated texts
|
|
589
|
+
throughout the view stack and provide the CAP runtimes with simple access to them.
|
|
590
|
+
But these views are considered as an implementation detail and are represented neither
|
|
591
|
+
in effective CSN nor in inferred CSN.
|
|
592
|
+
|
|
593
|
+
This means: In a view/projection entity in effective CSN, we may see whether an element is
|
|
594
|
+
localized or not, but we have no information on how to obtain the respective translated data.
|
|
595
|
+
This is a missing piece if we for example want to use effective CSN to define an API service.
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
### Effective CSN feature/flavor "Service Exposure Rendering"
|
|
599
|
+
|
|
600
|
+
For entities in a service, the compiler applies auto-redirection and auto-exposure
|
|
601
|
+
when producing Inferred CSN.
|
|
602
|
+
|
|
603
|
+
#### Auto-redirection
|
|
604
|
+
|
|
605
|
+
If an entity in a service has an association/composition with a target outside of the service, the compiler
|
|
606
|
+
tries to find a suitable "redirection target" inside the service. A suitable redirection target
|
|
607
|
+
is a view or projection on top of the original target, or an entity that includes the original target
|
|
608
|
+
(this is a simplified explanation, but we don't go into the details here).
|
|
609
|
+
If a suitable redirection target is found, the association/composition is automatically redirected to the new target.
|
|
610
|
+
|
|
611
|
+
<details>
|
|
612
|
+
<summary>Example</summary>
|
|
613
|
+
|
|
614
|
+
CDS:
|
|
615
|
+
```cds
|
|
616
|
+
entity E {
|
|
617
|
+
key id : Integer;
|
|
618
|
+
f : Association to F on f.id = id;
|
|
619
|
+
g : Association to G on g.id = id;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
entity F {
|
|
623
|
+
key id : Integer;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
entity G {
|
|
627
|
+
key id : Integer;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
service S {
|
|
631
|
+
entity PE as projection on E;
|
|
632
|
+
entity PF as projection on F;
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Inferred CSN:
|
|
637
|
+
```jsonc
|
|
638
|
+
{
|
|
639
|
+
"definitions": {
|
|
640
|
+
"E": {
|
|
641
|
+
"kind": "entity",
|
|
642
|
+
"elements": {
|
|
643
|
+
"id": {"key": true, "type": "cds.Integer"},
|
|
644
|
+
"f": {
|
|
645
|
+
"type": "cds.Association",
|
|
646
|
+
"target": "F",
|
|
647
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["id"]}]
|
|
648
|
+
},
|
|
649
|
+
"g": {
|
|
650
|
+
"type": "cds.Association",
|
|
651
|
+
"target": "G",
|
|
652
|
+
"on": [{"ref": ["g","id"]}, "=", {"ref": ["id"]}]
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
"F": {
|
|
657
|
+
"kind": "entity",
|
|
658
|
+
"elements": {
|
|
659
|
+
"id": {"key": true, "type": "cds.Integer"}
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
"G": {
|
|
663
|
+
"kind": "entity",
|
|
664
|
+
"elements": {
|
|
665
|
+
"id": {"key": true, "type": "cds.Integer"}
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
"S": {
|
|
669
|
+
"kind": "service"
|
|
670
|
+
},
|
|
671
|
+
"S.PE": {
|
|
672
|
+
"kind": "entity",
|
|
673
|
+
"projection": {
|
|
674
|
+
"from": {"ref": ["E"]}
|
|
675
|
+
},
|
|
676
|
+
"elements": {
|
|
677
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
678
|
+
"f": {
|
|
679
|
+
"type": "cds.Association",
|
|
680
|
+
"target": "PF", // has been redirected
|
|
681
|
+
"on": [{"ref": ["f","id"]},"=",{"ref": ["id"]}]
|
|
682
|
+
},
|
|
683
|
+
"g": {
|
|
684
|
+
"type": "cds.Association",
|
|
685
|
+
"target": "G", // still has target outside of service
|
|
686
|
+
"on": [{"ref": ["g","id"]},"=",{"ref": ["id"]}]
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
"S.PF": {
|
|
691
|
+
"kind": "entity",
|
|
692
|
+
"projection": {
|
|
693
|
+
"from": {"ref": ["F"]}
|
|
694
|
+
},
|
|
695
|
+
"elements": {
|
|
696
|
+
"id": {"key": true, "type": "cds.Integer"}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
```
|
|
702
|
+
</details>
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
#### Auto-exposure
|
|
706
|
+
|
|
707
|
+
If for a composition no suitable redirection target is found, the compiler generates a
|
|
708
|
+
projection on top of the original target in the service and redirects the composition to it.
|
|
709
|
+
If for an association no suitable redirection target is found but the original target
|
|
710
|
+
is annotated with `@cds.autoexpose : true`, the compiler generates a projection on top of the
|
|
711
|
+
original target in the service and redirects the association to it.
|
|
712
|
+
|
|
713
|
+
If after auto-redirection and auto-exposure an association still points to a target outside
|
|
714
|
+
of the service, this association is by default not removed but kept as is.
|
|
715
|
+
When option `effectiveServiceName` is used to reduce the output to one service, such
|
|
716
|
+
associations are removed (see section [Reduce to one service](#reduce-to-one-service)).
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
## Further transformations
|
|
720
|
+
|
|
721
|
+
Based on the Inferred CSN produced by the compiler, the following transformations are applied
|
|
722
|
+
when producing Effective CSN.
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
### Upper/lower case
|
|
726
|
+
|
|
727
|
+
Names are kept as they are in the model (usually camel case).
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
### Stay with CDS type system
|
|
731
|
+
|
|
732
|
+
No transformation applied for Effective CSN.
|
|
733
|
+
|
|
734
|
+
Keep the [CDS types](https://cap.cloud.sap/docs/cds/types#built-in-types). Don't map to e.g. HANA types.
|
|
735
|
+
|
|
736
|
+
CAP CDS allows to define elements of type String and Binary without a length.
|
|
737
|
+
When translating to SQL, for these elements a configurable default length is added.
|
|
738
|
+
_No_ default length is added for Effective CSN.
|
|
739
|
+
|
|
740
|
+
CAP CDS has the type `cds.UUID`. For SQL it is translated to a `cds.String(36)`. In Effective CSN it stays `cds.UUID`.
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
### Resolve simple types
|
|
744
|
+
|
|
745
|
+
By default, all references to simple types are resolved up to the respective primitive type
|
|
746
|
+
(also in CDL style casts, in entity parameters, and in action/function definitions).
|
|
747
|
+
Simple type definitions are removed from the CSN.
|
|
748
|
+
|
|
749
|
+
Example:
|
|
750
|
+
CDS:
|
|
751
|
+
```cds
|
|
752
|
+
type T : Integer;
|
|
753
|
+
type T2 : T;
|
|
754
|
+
type T3 : T2;
|
|
755
|
+
entity E {
|
|
756
|
+
a : T;
|
|
757
|
+
b : T3;
|
|
758
|
+
c : type of b;
|
|
759
|
+
d : type of c;
|
|
760
|
+
e : type of F:x; // also cross-entity
|
|
761
|
+
}
|
|
762
|
+
entity F {
|
|
763
|
+
x : T;
|
|
764
|
+
} actions {
|
|
765
|
+
action A(par: T2) returns T3;
|
|
766
|
+
}
|
|
767
|
+
entity V (par: T3) as select from E {
|
|
768
|
+
a : T3
|
|
769
|
+
}
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
<details>
|
|
773
|
+
<summary>Inferred CSN</summary>
|
|
774
|
+
|
|
775
|
+
Inferred CSN still contains the original type info.
|
|
776
|
+
```jsonc
|
|
777
|
+
{
|
|
778
|
+
"definitions": {
|
|
779
|
+
"T": {"kind": "type", "type": "cds.Integer"},
|
|
780
|
+
"T2": {"kind": "type", "type": "T"},
|
|
781
|
+
"T3": {"kind": "type", "type": "T2"},
|
|
782
|
+
"E": {
|
|
783
|
+
"kind": "entity",
|
|
784
|
+
"elements": {
|
|
785
|
+
"a": {"type": "T"},
|
|
786
|
+
"b": {"type": "T3"},
|
|
787
|
+
"c": {"type": {"ref": ["E", "b"]}},
|
|
788
|
+
"d": {"type": {"ref": ["E", "c"]}},
|
|
789
|
+
"e": {"type": {"ref": ["F", "x"]}}
|
|
790
|
+
}
|
|
791
|
+
},
|
|
792
|
+
"F": {
|
|
793
|
+
"kind": "entity",
|
|
794
|
+
"elements": {
|
|
795
|
+
"x": {"type": "T"}
|
|
796
|
+
},
|
|
797
|
+
"actions": {
|
|
798
|
+
"A": {
|
|
799
|
+
"kind": "action",
|
|
800
|
+
"params": {
|
|
801
|
+
"par": {"type": "T2"}
|
|
802
|
+
},
|
|
803
|
+
"returns": {"type": "T3"}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
"V": {
|
|
808
|
+
"kind": "entity",
|
|
809
|
+
"params": {
|
|
810
|
+
"par": {"type": "T3"}
|
|
811
|
+
},
|
|
812
|
+
"query": {
|
|
813
|
+
"SELECT": {
|
|
814
|
+
"from": {"ref": ["E"]},
|
|
815
|
+
"columns": [{
|
|
816
|
+
"ref": ["a"], "cast": {"type": "T3"}
|
|
817
|
+
}]
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
"elements": {
|
|
821
|
+
"a": {"type": "T3"}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
</details>
|
|
829
|
+
|
|
830
|
+
<details>
|
|
831
|
+
<summary>Effective CSN</summary>
|
|
832
|
+
|
|
833
|
+
```json
|
|
834
|
+
{
|
|
835
|
+
"definitions": {
|
|
836
|
+
"E": {
|
|
837
|
+
"kind": "entity",
|
|
838
|
+
"elements": {
|
|
839
|
+
"a": {"type": "cds.Integer"},
|
|
840
|
+
"b": {"type": "cds.Integer"},
|
|
841
|
+
"c": {"type": "cds.Integer"},
|
|
842
|
+
"d": {"type": "cds.Integer"},
|
|
843
|
+
"e": {"type": "cds.Integer"}
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
"F": {
|
|
847
|
+
"kind": "entity",
|
|
848
|
+
"elements": {
|
|
849
|
+
"x": {"type": "cds.Integer"}
|
|
850
|
+
},
|
|
851
|
+
"actions": {
|
|
852
|
+
"A": {
|
|
853
|
+
"kind": "action",
|
|
854
|
+
"params": {
|
|
855
|
+
"par": {"type": "cds.Integer"}
|
|
856
|
+
},
|
|
857
|
+
"returns": {"type": "cds.Integer"}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
},
|
|
861
|
+
"V": {
|
|
862
|
+
"kind": "entity",
|
|
863
|
+
"params": {
|
|
864
|
+
"par": {"type": "cds.Integer"}
|
|
865
|
+
},
|
|
866
|
+
"query": {
|
|
867
|
+
"SELECT": {
|
|
868
|
+
"from": {"ref": ["E"]},
|
|
869
|
+
"columns": [{
|
|
870
|
+
"ref": ["a"], "cast": {"type": "cds.Integer"}
|
|
871
|
+
}]
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
"elements": {
|
|
875
|
+
"a": {"type": "cds.Integer"}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
```
|
|
881
|
+
</details>
|
|
882
|
+
|
|
883
|
+
#### Option `resolveSimpleTypes`
|
|
884
|
+
|
|
885
|
+
When option `resolveSimpleTypes` is set to `false` (default is `true`), references to simple types
|
|
886
|
+
are not resolved and the simple type definitions are kept. In this case, there is no difference
|
|
887
|
+
between Inferred CSN and Effective CSN.
|
|
888
|
+
The behavior for simple types is not completely consistent when this option is set to `false`.
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
> [!WARNING]
|
|
892
|
+
> This option is __experimental__ and must not be used for productive use cases.
|
|
893
|
+
> You must not rely on the resulting CSN representation.
|
|
894
|
+
> Name and behavior of this option may change in the future.
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
#### Note on references to built-in types
|
|
898
|
+
|
|
899
|
+
In CAP, a CSN may contain references to built-in types (deprecated, should only occur in old CSNs).
|
|
900
|
+
In Effective CSN, such references are replaced by the built-in types themselves:
|
|
901
|
+
```json
|
|
902
|
+
"elements": {
|
|
903
|
+
"a": { "type": { "ref": ["cds.Integer"]} }
|
|
904
|
+
}
|
|
905
|
+
```
|
|
906
|
+
Effective CSN:
|
|
907
|
+
```json
|
|
908
|
+
"elements": {
|
|
909
|
+
"a": {"type": "cds.Integer"}
|
|
910
|
+
}
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
#### Note on managed associations
|
|
914
|
+
|
|
915
|
+
A named type can also be a managed association:
|
|
916
|
+
```cds
|
|
917
|
+
type MyAssoc : Association to E;
|
|
918
|
+
```
|
|
919
|
+
References to such types are resolved, too, and in a later step [Resolve Managed Associations](#resolve-managed-associations)
|
|
920
|
+
the managed association is turned into an unmanaged one.
|
|
921
|
+
|
|
922
|
+
This happens even if option `resolveSimpleTypes` is set to `false`. However, the behavior of such types
|
|
923
|
+
when this experimental option is disabled is undefined, and consumers must not rely on the resulting
|
|
924
|
+
CSN representation.
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
#### Note on retaining type information in the future
|
|
928
|
+
|
|
929
|
+
Having the simple types in the CSN in principle is desired in order to retain
|
|
930
|
+
the semantic information that is inherent to a type. But CDS allows type chains, which
|
|
931
|
+
are quite complicated to handle. So, for the time being, the types are resolved.
|
|
932
|
+
|
|
933
|
+
As a workaround, one could add annotations like
|
|
934
|
+
```cds
|
|
935
|
+
@workaround: 'I am a T'
|
|
936
|
+
type T : Integer;
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
### Flatten structured types
|
|
941
|
+
|
|
942
|
+
Type references to structured types are resolved.
|
|
943
|
+
Structured elements are flattened, all references are adapted accordingly.
|
|
944
|
+
Definitions of named structured types are removed from the CSN.
|
|
945
|
+
|
|
946
|
+
Example:
|
|
947
|
+
CDS:
|
|
948
|
+
```cds
|
|
949
|
+
type S {
|
|
950
|
+
x : Integer;
|
|
951
|
+
y : Integer;
|
|
952
|
+
};
|
|
953
|
+
type S2 : S;
|
|
954
|
+
|
|
955
|
+
entity E {
|
|
956
|
+
s : S2;
|
|
957
|
+
t {
|
|
958
|
+
x : Integer;
|
|
959
|
+
y : Integer;
|
|
960
|
+
}
|
|
961
|
+
e : Association to E on e.t.x = s.y;
|
|
962
|
+
}
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
<details>
|
|
966
|
+
<summary>Effective CSN</summary>
|
|
967
|
+
|
|
968
|
+
```json
|
|
969
|
+
{
|
|
970
|
+
"definitions": {
|
|
971
|
+
"E": {
|
|
972
|
+
"kind": "entity",
|
|
973
|
+
"elements": {
|
|
974
|
+
"s_x": {"type": "cds.Integer"},
|
|
975
|
+
"s_y": {"type": "cds.Integer"},
|
|
976
|
+
"t_x": {"type": "cds.Integer"},
|
|
977
|
+
"t_y": {"type": "cds.Integer"},
|
|
978
|
+
"e": {
|
|
979
|
+
"type": "cds.Association",
|
|
980
|
+
"target": "E",
|
|
981
|
+
"on": [{"ref": ["e", "t_x"]}, "=", {"ref": ["s_y"]}]
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
</details>
|
|
990
|
+
|
|
991
|
+
<details>
|
|
992
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
993
|
+
|
|
994
|
+
```cds
|
|
995
|
+
entity E {
|
|
996
|
+
s_x : Integer;
|
|
997
|
+
s_y : Integer;
|
|
998
|
+
t_x : Integer;
|
|
999
|
+
t_y : Integer;
|
|
1000
|
+
e : Association to E on e.t_x = s_y;
|
|
1001
|
+
}
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
</details>
|
|
1005
|
+
|
|
1006
|
+
<br />
|
|
1007
|
+
|
|
1008
|
+
References to the leaves of structured elements are adapted, e.g. in views.
|
|
1009
|
+
|
|
1010
|
+
CDS:
|
|
1011
|
+
```cds
|
|
1012
|
+
entity V1 as select from E {
|
|
1013
|
+
s.x // resulting element name is x
|
|
1014
|
+
} where s.x = t.y group by s.x;
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
<details>
|
|
1018
|
+
<summary>Effective CSN</summary>
|
|
1019
|
+
|
|
1020
|
+
```jsonc
|
|
1021
|
+
{
|
|
1022
|
+
"definitions": {
|
|
1023
|
+
"E": { /*...*/ },
|
|
1024
|
+
"V1": {
|
|
1025
|
+
"kind": "entity",
|
|
1026
|
+
"query": {
|
|
1027
|
+
"SELECT": {
|
|
1028
|
+
"from": {"ref": ["E"]},
|
|
1029
|
+
"columns": [
|
|
1030
|
+
{ "ref": ["s_x"], "as": "x" }
|
|
1031
|
+
],
|
|
1032
|
+
"groupBy": [{"ref": ["s_x"]}],
|
|
1033
|
+
"where": [{"ref": ["s_x"]}, "=", {"ref": ["t_y"]}]
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
"elements": {
|
|
1037
|
+
"x": {"type": "cds.Integer"}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
</details>
|
|
1045
|
+
|
|
1046
|
+
<details>
|
|
1047
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
1048
|
+
|
|
1049
|
+
```cds
|
|
1050
|
+
entity V1 as select from E {
|
|
1051
|
+
s_x as x
|
|
1052
|
+
} where s_x = t_y group by s_x;
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
</details>
|
|
1056
|
+
|
|
1057
|
+
<br />
|
|
1058
|
+
|
|
1059
|
+
References to the structured elements themselves are expanded.
|
|
1060
|
+
|
|
1061
|
+
CDS:
|
|
1062
|
+
```cds
|
|
1063
|
+
entity V2 as select from E {
|
|
1064
|
+
s
|
|
1065
|
+
} where s = t group by s;
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
<details>
|
|
1069
|
+
<summary>Effective CSN</summary>
|
|
1070
|
+
|
|
1071
|
+
```jsonc
|
|
1072
|
+
{
|
|
1073
|
+
"definitions": {
|
|
1074
|
+
"E": { /*...*/ },
|
|
1075
|
+
"V2": {
|
|
1076
|
+
"kind": "entity",
|
|
1077
|
+
"query": {
|
|
1078
|
+
"SELECT": {
|
|
1079
|
+
"from": {"ref": ["E"]},
|
|
1080
|
+
"columns": [
|
|
1081
|
+
{"ref": ["E","s_x"]},
|
|
1082
|
+
{"ref": ["E","s_y"]}
|
|
1083
|
+
],
|
|
1084
|
+
"groupBy": [{"ref": ["E","s_x"]}, {"ref": ["E","s_y"]}],
|
|
1085
|
+
"where": [{"xpr": [{"ref": ["s_x"]}, "=", {"ref": ["t_x"]},
|
|
1086
|
+
"and",
|
|
1087
|
+
{"ref": ["s_y"]}, "=", {"ref": ["t_y"]}]}]
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
"elements": {
|
|
1091
|
+
"s_x": {"type": "cds.Integer"},
|
|
1092
|
+
"s_y": {"type": "cds.Integer"}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
</details>
|
|
1100
|
+
|
|
1101
|
+
<details>
|
|
1102
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
1103
|
+
|
|
1104
|
+
```cds
|
|
1105
|
+
entity V2 as select from E {
|
|
1106
|
+
E.s_x,
|
|
1107
|
+
E.s_y
|
|
1108
|
+
} where s_x = t_x and s_y = t_y group by E.s_x, E.s_y;
|
|
1109
|
+
```
|
|
1110
|
+
|
|
1111
|
+
</details>
|
|
1112
|
+
|
|
1113
|
+
<br />
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
#### View parameters
|
|
1117
|
+
|
|
1118
|
+
Currently, a structured parameter leads to an error.
|
|
1119
|
+
This may change in the future, so that flattening is also applied to view parameters.
|
|
1120
|
+
|
|
1121
|
+
<details>
|
|
1122
|
+
<summary>Example</summary>
|
|
1123
|
+
|
|
1124
|
+
CDS:
|
|
1125
|
+
```cds
|
|
1126
|
+
type S {
|
|
1127
|
+
x : Integer;
|
|
1128
|
+
y : Integer;
|
|
1129
|
+
}
|
|
1130
|
+
entity E {
|
|
1131
|
+
key id : Integer;
|
|
1132
|
+
s : S;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
entity V ( p1 : S, p2 : { x : Integer; y : Integer; })
|
|
1136
|
+
as select from E {
|
|
1137
|
+
id
|
|
1138
|
+
} where s = :p1;
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
Could result in this Effective CSN:
|
|
1142
|
+
```cds
|
|
1143
|
+
entity E {
|
|
1144
|
+
key id : Integer;
|
|
1145
|
+
s_x : Integer;
|
|
1146
|
+
s_y : Integer;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
entity V ( p1_x : Integer, p1_y : Integer, p2_x : Integer, p2_y : Integer)
|
|
1150
|
+
as select from E {
|
|
1151
|
+
id
|
|
1152
|
+
} where s_x = :p1_x and s_y = :p1_y;
|
|
1153
|
+
```
|
|
1154
|
+
</details>
|
|
1155
|
+
|
|
1156
|
+
#### Action/function parameters
|
|
1157
|
+
|
|
1158
|
+
The behavior of non-primitive action and function parameters in effective CSN
|
|
1159
|
+
is __not defined__. Behavior may change in the future.
|
|
1160
|
+
|
|
1161
|
+
Current behavior: Structures are inlined, but not flattened. If a structure
|
|
1162
|
+
contains a managed association, it is converted to an unmanaged one plus explicit FK.
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
### Resolve Managed Associations
|
|
1166
|
+
|
|
1167
|
+
Managed associations are converted to unmanaged associations, and explicit foreign key elements are added.
|
|
1168
|
+
The `keys` array (added by the compiler in Inferred CSN) vanishes.
|
|
1169
|
+
|
|
1170
|
+
Example:
|
|
1171
|
+
CDS:
|
|
1172
|
+
```cds
|
|
1173
|
+
entity E {
|
|
1174
|
+
f : Association to F;
|
|
1175
|
+
}
|
|
1176
|
+
entity F { key id : Integer; x : Integer; }
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
<details>
|
|
1180
|
+
<summary>Inferred CSN</summary>
|
|
1181
|
+
|
|
1182
|
+
```jsonc
|
|
1183
|
+
{
|
|
1184
|
+
"definitions": {
|
|
1185
|
+
"E": {
|
|
1186
|
+
"kind": "entity",
|
|
1187
|
+
"elements": {
|
|
1188
|
+
"f": {
|
|
1189
|
+
"type": "cds.Association",
|
|
1190
|
+
"target": "F",
|
|
1191
|
+
"keys": [{"ref": ["id"]}]
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
"F": { /*...*/ }
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
</details>
|
|
1201
|
+
|
|
1202
|
+
<details>
|
|
1203
|
+
<summary>Effective CSN</summary>
|
|
1204
|
+
|
|
1205
|
+
```json
|
|
1206
|
+
{
|
|
1207
|
+
"definitions": {
|
|
1208
|
+
"E": {
|
|
1209
|
+
"kind": "entity",
|
|
1210
|
+
"elements": {
|
|
1211
|
+
"f": {
|
|
1212
|
+
"type": "cds.Association",
|
|
1213
|
+
"target": "F",
|
|
1214
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["f_id"]}]
|
|
1215
|
+
},
|
|
1216
|
+
"f_id": {
|
|
1217
|
+
"type": "cds.Integer"
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
},
|
|
1221
|
+
"F": {
|
|
1222
|
+
"kind": "entity",
|
|
1223
|
+
"elements": {
|
|
1224
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
1225
|
+
"x": {"type": "cds.Integer"}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
```
|
|
1231
|
+
|
|
1232
|
+
</details>
|
|
1233
|
+
|
|
1234
|
+
<details>
|
|
1235
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
1236
|
+
|
|
1237
|
+
```cds
|
|
1238
|
+
entity E {
|
|
1239
|
+
f_id : Integer;
|
|
1240
|
+
f : Association to F on f.id = f_id;
|
|
1241
|
+
}
|
|
1242
|
+
entity F { key id : Integer; x : Integer; }
|
|
1243
|
+
```
|
|
1244
|
+
</details>
|
|
1245
|
+
|
|
1246
|
+
<br />
|
|
1247
|
+
|
|
1248
|
+
In the definition of an unmanaged association (also in the ON condition of explicit JOINs)
|
|
1249
|
+
it is possible to reference the foreign keys of a "neighbor" managed association.
|
|
1250
|
+
When resolving managed associations, this is always interpreted as accessing the local
|
|
1251
|
+
foreign key element, never as "navigating" the association to the target:
|
|
1252
|
+
|
|
1253
|
+
Example:
|
|
1254
|
+
CDS:
|
|
1255
|
+
```cds
|
|
1256
|
+
entity E {
|
|
1257
|
+
f : Association to F;
|
|
1258
|
+
g : Association to G on g.id = f.id; // f.x is NOT allowed
|
|
1259
|
+
}
|
|
1260
|
+
entity F { key id : Integer; x : Integer; }
|
|
1261
|
+
entity G { key id : Integer; }
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
<details>
|
|
1265
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
1266
|
+
|
|
1267
|
+
```cds
|
|
1268
|
+
entity E {
|
|
1269
|
+
f_id : Integer;
|
|
1270
|
+
f : Association to F on f.id = f_id;
|
|
1271
|
+
g : Association to G on g.id = f_id;
|
|
1272
|
+
}
|
|
1273
|
+
entity F { /*...*/ }
|
|
1274
|
+
entity G { /*...*/ }
|
|
1275
|
+
```
|
|
1276
|
+
</details>
|
|
1277
|
+
|
|
1278
|
+
<br />
|
|
1279
|
+
|
|
1280
|
+
Publication of a managed association in a view/projection is also adapted
|
|
1281
|
+
and results in publishing the foreign key and the corresponding unmanaged association.
|
|
1282
|
+
|
|
1283
|
+
Example:
|
|
1284
|
+
CDS:
|
|
1285
|
+
```cds
|
|
1286
|
+
entity E {
|
|
1287
|
+
f : Association to F; // < managed
|
|
1288
|
+
}
|
|
1289
|
+
entity F {
|
|
1290
|
+
key id : Integer;
|
|
1291
|
+
}
|
|
1292
|
+
view V as select from E {
|
|
1293
|
+
f // < managed
|
|
1294
|
+
}
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
<details>
|
|
1298
|
+
<summary>Effective CSN</summary>
|
|
1299
|
+
|
|
1300
|
+
```jsonc
|
|
1301
|
+
{
|
|
1302
|
+
"definitions": {
|
|
1303
|
+
"E": {
|
|
1304
|
+
"kind": "entity",
|
|
1305
|
+
"elements": {
|
|
1306
|
+
"f": {
|
|
1307
|
+
"type": "cds.Association",
|
|
1308
|
+
"target": "F",
|
|
1309
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["f_id"]}]
|
|
1310
|
+
},
|
|
1311
|
+
"f_id": {"type": "cds.Integer"}
|
|
1312
|
+
}
|
|
1313
|
+
},
|
|
1314
|
+
"F": { /*...*/ },
|
|
1315
|
+
"V": {
|
|
1316
|
+
"kind": "entity",
|
|
1317
|
+
"query": {
|
|
1318
|
+
"SELECT": {
|
|
1319
|
+
"from": {"ref": ["E"]},
|
|
1320
|
+
"columns": [
|
|
1321
|
+
{"ref": ["f"]},
|
|
1322
|
+
{"ref": ["f_id"]}
|
|
1323
|
+
]
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
"elements": {
|
|
1327
|
+
"f": {
|
|
1328
|
+
"type": "cds.Association",
|
|
1329
|
+
"target": "F",
|
|
1330
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["f_id"]}
|
|
1331
|
+
]
|
|
1332
|
+
},
|
|
1333
|
+
"f_id": {"type": "cds.Integer"}
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
</details>
|
|
1341
|
+
|
|
1342
|
+
<details>
|
|
1343
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
1344
|
+
|
|
1345
|
+
```cds
|
|
1346
|
+
entity E {
|
|
1347
|
+
f_id : Integer;
|
|
1348
|
+
f : Association to F on f.id = f_id; // < unmanaged
|
|
1349
|
+
}
|
|
1350
|
+
entity F {
|
|
1351
|
+
key id : Integer;
|
|
1352
|
+
}
|
|
1353
|
+
view V as select from E {
|
|
1354
|
+
f_id,
|
|
1355
|
+
f // < unmanaged
|
|
1356
|
+
}
|
|
1357
|
+
```
|
|
1358
|
+
</details>
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
#### Ambiguity
|
|
1362
|
+
|
|
1363
|
+
Let's have a look at this view:
|
|
1364
|
+
```cds
|
|
1365
|
+
// original CDS source
|
|
1366
|
+
view V as select from E {
|
|
1367
|
+
f.id
|
|
1368
|
+
}
|
|
1369
|
+
```
|
|
1370
|
+
There are two possibilities to interpret the path `f.id`:
|
|
1371
|
+
1. Select the local foreign key element of the managed association
|
|
1372
|
+
2. Navigate to the target entity and select the key element there
|
|
1373
|
+
|
|
1374
|
+
When resolving unmanaged associations, option 1 results in
|
|
1375
|
+
```cds
|
|
1376
|
+
// CDS source equivalent to Effective CSN
|
|
1377
|
+
view V as select from E {
|
|
1378
|
+
f_id as id
|
|
1379
|
+
}
|
|
1380
|
+
```
|
|
1381
|
+
while option 2 yields
|
|
1382
|
+
```cds
|
|
1383
|
+
// CDS source equivalent to Effective CSN
|
|
1384
|
+
view V as select from E {
|
|
1385
|
+
f.id
|
|
1386
|
+
}
|
|
1387
|
+
```
|
|
1388
|
+
|
|
1389
|
+
We _always_ choose option 1, i.e. we interpret and translate `f.id`
|
|
1390
|
+
as access to the FK element `f_id`.
|
|
1391
|
+
This doesn't change if there are other paths like `f.val` where `val` is not a FK
|
|
1392
|
+
(in SQL this would lead to a join, and then `f.id` would be changed to get `id` from the target).
|
|
1393
|
+
This also holds for paths in the clauses WHERE, GROUP BY, and ORDER BY.
|
|
1394
|
+
|
|
1395
|
+
|
|
1396
|
+
#### Annotations for FKs
|
|
1397
|
+
|
|
1398
|
+
When resolving managed associations, all annotations of the managed association are copied
|
|
1399
|
+
to the generated FK elements (like for OData).
|
|
1400
|
+
|
|
1401
|
+
Example:
|
|
1402
|
+
CDS:
|
|
1403
|
+
```cds
|
|
1404
|
+
entity E {
|
|
1405
|
+
@Foo: 8
|
|
1406
|
+
f : Association to F;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
entity F { key id : Integer; x : Integer; }
|
|
1410
|
+
```
|
|
1411
|
+
|
|
1412
|
+
<details>
|
|
1413
|
+
<summary>Effective CSN</summary>
|
|
1414
|
+
|
|
1415
|
+
```jsonc
|
|
1416
|
+
{
|
|
1417
|
+
"definitions": {
|
|
1418
|
+
"E": {
|
|
1419
|
+
"kind": "entity",
|
|
1420
|
+
"elements": {
|
|
1421
|
+
"f": {
|
|
1422
|
+
"@Foo": 8,
|
|
1423
|
+
"type": "cds.Association",
|
|
1424
|
+
"target": "F",
|
|
1425
|
+
"on": [{"ref": ["f","id"]},"=",{"ref": ["f_id"]}]
|
|
1426
|
+
},
|
|
1427
|
+
"f_id": {
|
|
1428
|
+
"@Foo": 8, // < anno copied to FK
|
|
1429
|
+
"type": "cds.Integer"
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
},
|
|
1433
|
+
"F": { ... }
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
```
|
|
1437
|
+
</details>
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
#### No unmanaged association inside structures
|
|
1441
|
+
|
|
1442
|
+
There is a _potential_ problem: The compiler allows to define managed associations
|
|
1443
|
+
inside structured elements/types, but unmanaged associations inside structured elements/types are
|
|
1444
|
+
not supported. Thus, if we transform a managed association inside a structured element into an
|
|
1445
|
+
unmanaged association, the resulting CSN can no longer be compiled.
|
|
1446
|
+
|
|
1447
|
+
In the context of Effective CSN, however, that is not a real problem, as we also flatten all structured elements.
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
### Keep array types (many)
|
|
1451
|
+
|
|
1452
|
+
For Effective CSN, we don't replace `items`, but keep it as it is.
|
|
1453
|
+
|
|
1454
|
+
Type references inside `items` are resolved, references to structured types are inlined.
|
|
1455
|
+
|
|
1456
|
+
Example:
|
|
1457
|
+
CDS:
|
|
1458
|
+
```cds
|
|
1459
|
+
type T : String;
|
|
1460
|
+
type S {
|
|
1461
|
+
x: Integer;
|
|
1462
|
+
y: T;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
entity E {
|
|
1466
|
+
emails : many T;
|
|
1467
|
+
someS : many S;
|
|
1468
|
+
}
|
|
1469
|
+
```
|
|
1470
|
+
|
|
1471
|
+
<details>
|
|
1472
|
+
<summary>Effective CSN</summary>
|
|
1473
|
+
|
|
1474
|
+
```json
|
|
1475
|
+
{
|
|
1476
|
+
"definitions": {
|
|
1477
|
+
"E": {
|
|
1478
|
+
"kind": "entity",
|
|
1479
|
+
"elements": {
|
|
1480
|
+
"emails": {
|
|
1481
|
+
"items": {
|
|
1482
|
+
"type": "cds.String"
|
|
1483
|
+
}
|
|
1484
|
+
},
|
|
1485
|
+
"someS": {
|
|
1486
|
+
"items": {
|
|
1487
|
+
"elements": {
|
|
1488
|
+
"x": {"type": "cds.Integer"},
|
|
1489
|
+
"y": {"type": "cds.String"}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
```
|
|
1498
|
+
</details>
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
### Cleanup: remove no longer needed objects and attributes
|
|
1502
|
+
|
|
1503
|
+
Inferred CSN still contains some definitions and properties that are not needed in
|
|
1504
|
+
Effective CSN (as it is not intended to use it for further modelling).
|
|
1505
|
+
|
|
1506
|
+
We remove property `namespace`.
|
|
1507
|
+
|
|
1508
|
+
After applying _all_ of
|
|
1509
|
+
* Apply extensions and includes
|
|
1510
|
+
* Unfold managed composition of aspect
|
|
1511
|
+
* Resolve simple type references (could refer to the type of an aspect element)
|
|
1512
|
+
* Flatten structured types (could refer to the type of an aspect element)
|
|
1513
|
+
|
|
1514
|
+
in Effective CSN we
|
|
1515
|
+
* remove all aspects (they are mere building blocks for modelling)
|
|
1516
|
+
* remove all attributes `targetAspect`
|
|
1517
|
+
* remove property `extensions` (unapplied annotations)
|
|
1518
|
+
* remove property `includes` (property of an entity that lists all included objects)
|
|
1519
|
+
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
See examples in [Extensions and Includes are applied](#extensions-and-includes-are-applied)
|
|
1523
|
+
and [Composition of aspect is unfolded](#composition-of-aspect-is-unfolded).
|
|
1524
|
+
|
|
1525
|
+
|
|
1526
|
+
### Virtual elements
|
|
1527
|
+
|
|
1528
|
+
No transformation applied for Effective CSN.
|
|
1529
|
+
|
|
1530
|
+
Virtual elements are elements that are not present in the persistence layer.
|
|
1531
|
+
They can be used in an API (e.g. OData) and need to be handled in custom code.
|
|
1532
|
+
|
|
1533
|
+
We keep them in Effective CSN.
|
|
1534
|
+
|
|
1535
|
+
Example:
|
|
1536
|
+
CDS:
|
|
1537
|
+
```cds
|
|
1538
|
+
entity E {
|
|
1539
|
+
key id : Integer;
|
|
1540
|
+
a : Integer;
|
|
1541
|
+
virtual v : Integer;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
entity V as select from E {
|
|
1545
|
+
a,
|
|
1546
|
+
v
|
|
1547
|
+
};
|
|
1548
|
+
```
|
|
1549
|
+
|
|
1550
|
+
<details>
|
|
1551
|
+
<summary>Effective CSN</summary>
|
|
1552
|
+
|
|
1553
|
+
```json
|
|
1554
|
+
{
|
|
1555
|
+
"definitions": {
|
|
1556
|
+
"E": {
|
|
1557
|
+
"kind": "entity",
|
|
1558
|
+
"elements": {
|
|
1559
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
1560
|
+
"a": {"type": "cds.Integer"},
|
|
1561
|
+
"v": {"@Core.Computed": true,
|
|
1562
|
+
"virtual": true, // <
|
|
1563
|
+
"type": "cds.Integer"
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
},
|
|
1567
|
+
"V": {
|
|
1568
|
+
"kind": "entity",
|
|
1569
|
+
"query": {
|
|
1570
|
+
"SELECT": {
|
|
1571
|
+
"from": {"ref": ["E"]},
|
|
1572
|
+
"columns": [
|
|
1573
|
+
{"ref": ["a"]},
|
|
1574
|
+
{"ref": ["v"]}
|
|
1575
|
+
]
|
|
1576
|
+
}
|
|
1577
|
+
},
|
|
1578
|
+
"elements": {
|
|
1579
|
+
"a": {"type": "cds.Integer"},
|
|
1580
|
+
"v": {"@Core.Computed": true,
|
|
1581
|
+
"virtual": true, // <
|
|
1582
|
+
"type": "cds.Integer"
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
```
|
|
1589
|
+
</details>
|
|
1590
|
+
|
|
1591
|
+
#### Note on removing virtual elements
|
|
1592
|
+
|
|
1593
|
+
It is not possible to simply remove the virtual elements from the CSN, as they can occur also
|
|
1594
|
+
in expressions, e.g. in a where condition:
|
|
1595
|
+
```cds
|
|
1596
|
+
entity V2 as select from E {
|
|
1597
|
+
a
|
|
1598
|
+
} where v > 4;
|
|
1599
|
+
```
|
|
1600
|
+
When generating SQL, the CAP compiler ignores all virtual element definitions and also ignores
|
|
1601
|
+
all select items that simply select a virtual element. But it issues an error, when a virtual element
|
|
1602
|
+
occurs in an expression.
|
|
1603
|
+
|
|
1604
|
+
|
|
1605
|
+
### Enums
|
|
1606
|
+
|
|
1607
|
+
CAP CDS allows to define enums. Currently they can only be used in annotations.
|
|
1608
|
+
We keep them in Effective CSN.
|
|
1609
|
+
|
|
1610
|
+
```cds
|
|
1611
|
+
// original CDS source
|
|
1612
|
+
entity E {
|
|
1613
|
+
@Color: #green
|
|
1614
|
+
key id : Integer;
|
|
1615
|
+
color : Integer enum {red=1; green=2; blue=3;}
|
|
1616
|
+
}
|
|
1617
|
+
```
|
|
1618
|
+
|
|
1619
|
+
<details>
|
|
1620
|
+
<summary>Effective CSN</summary>
|
|
1621
|
+
|
|
1622
|
+
```json
|
|
1623
|
+
{
|
|
1624
|
+
"definitions": {
|
|
1625
|
+
"E": {
|
|
1626
|
+
"kind": "entity",
|
|
1627
|
+
"elements": {
|
|
1628
|
+
"id": {
|
|
1629
|
+
"@Color": {"#": "green"},
|
|
1630
|
+
"key": true,
|
|
1631
|
+
"type": "cds.Integer"
|
|
1632
|
+
},
|
|
1633
|
+
"color": {
|
|
1634
|
+
"type": "cds.Integer",
|
|
1635
|
+
"enum": {
|
|
1636
|
+
"red": {"val": 1},
|
|
1637
|
+
"green": {"val": 2},
|
|
1638
|
+
"blue": {"val": 3}
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
```
|
|
1646
|
+
|
|
1647
|
+
</details>
|
|
1648
|
+
|
|
1649
|
+
|
|
1650
|
+
### Session variables
|
|
1651
|
+
|
|
1652
|
+
Session variables are kept unchanged in Effective CSN.
|
|
1653
|
+
Mapping to the respective HANA expression is done by the consumer.
|
|
1654
|
+
|
|
1655
|
+
Expressions can contain references to so called session variables. Supported variables for
|
|
1656
|
+
view definitions and the corresponding replacements for HANA are:
|
|
1657
|
+
|
|
1658
|
+
| name | HANA |
|
|
1659
|
+
| --- | --- |
|
|
1660
|
+
| $user.id | `SESSION_CONTEXT('APPLICATIONUSER')` |
|
|
1661
|
+
| $user.locale | `SESSION_CONTEXT('LOCALE')` |
|
|
1662
|
+
| $valid.from | `TO_TIMESTAMP(SESSION_CONTEXT('VALID-FROM'))` |
|
|
1663
|
+
| $valid.to | `TO_TIMESTAMP(SESSION_CONTEXT('VALID-TO'))` |
|
|
1664
|
+
| $at.from | `TO_TIMESTAMP(SESSION_CONTEXT('VALID-FROM'))` |
|
|
1665
|
+
| $at.to | `TO_TIMESTAMP(SESSION_CONTEXT('VALID-TO'))` |
|
|
1666
|
+
| $now | `CURRENT_TIMESTAMP` |
|
|
1667
|
+
|
|
1668
|
+
Remarks:
|
|
1669
|
+
* `$user.locale` is used in the generated association `localized` for localized elements.
|
|
1670
|
+
* `$user.id` may be used for accessing personalized table content
|
|
1671
|
+
* `$valid.from/to` and `$at.from/to` are used for feature "temporal", which is not yet official
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
Example:
|
|
1675
|
+
```cds
|
|
1676
|
+
// original CDS source
|
|
1677
|
+
entity E {
|
|
1678
|
+
key id : Integer;
|
|
1679
|
+
name : String;
|
|
1680
|
+
createdAt : Timestamp default $now;
|
|
1681
|
+
}
|
|
1682
|
+
entity V as select from E {
|
|
1683
|
+
id
|
|
1684
|
+
} where name = $user.id;
|
|
1685
|
+
```
|
|
1686
|
+
|
|
1687
|
+
<details>
|
|
1688
|
+
<summary>Effective CSN</summary>
|
|
1689
|
+
|
|
1690
|
+
```json
|
|
1691
|
+
{
|
|
1692
|
+
"definitions": {
|
|
1693
|
+
"E": {
|
|
1694
|
+
"kind": "entity",
|
|
1695
|
+
"elements": {
|
|
1696
|
+
"id": {
|
|
1697
|
+
"key": true,
|
|
1698
|
+
"type": "cds.Integer"
|
|
1699
|
+
},
|
|
1700
|
+
"name": {
|
|
1701
|
+
"type": "cds.String"
|
|
1702
|
+
},
|
|
1703
|
+
"createdAt": {
|
|
1704
|
+
"type": "cds.Timestamp",
|
|
1705
|
+
"default": {"ref": ["$now"]}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
},
|
|
1709
|
+
"V": {
|
|
1710
|
+
"kind": "entity",
|
|
1711
|
+
"query": {
|
|
1712
|
+
"SELECT": {
|
|
1713
|
+
"from": {"ref": ["E"]},
|
|
1714
|
+
"columns": [{"ref": ["id"]}],
|
|
1715
|
+
"where": [{"ref": ["name"]}, "=", {"ref": ["$user","id"]}]
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
"elements": {
|
|
1719
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
```
|
|
1725
|
+
|
|
1726
|
+
</details>
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
### Actions and Functions
|
|
1730
|
+
|
|
1731
|
+
CAP CDS supports the definition of bound/unbound actions and functions.
|
|
1732
|
+
We keep them in Effective CSN.
|
|
1733
|
+
|
|
1734
|
+
Example:
|
|
1735
|
+
```cds
|
|
1736
|
+
// original CDS source
|
|
1737
|
+
entity E {
|
|
1738
|
+
key id : Integer;
|
|
1739
|
+
} actions {
|
|
1740
|
+
action A(p : Integer);
|
|
1741
|
+
function F(p : Integer) returns String;
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
service S {
|
|
1745
|
+
action A(p : Integer);
|
|
1746
|
+
function F(p : Integer) returns String;
|
|
1747
|
+
}
|
|
1748
|
+
```
|
|
1749
|
+
|
|
1750
|
+
<details>
|
|
1751
|
+
<summary>Effective CSN</summary>
|
|
1752
|
+
|
|
1753
|
+
```json
|
|
1754
|
+
{
|
|
1755
|
+
"definitions": {
|
|
1756
|
+
"E": {
|
|
1757
|
+
"kind": "entity",
|
|
1758
|
+
"elements": {
|
|
1759
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
1760
|
+
},
|
|
1761
|
+
"actions": {
|
|
1762
|
+
"A": {
|
|
1763
|
+
"kind": "action",
|
|
1764
|
+
"params": {"p": {"type": "cds.Integer"}}
|
|
1765
|
+
},
|
|
1766
|
+
"F": {
|
|
1767
|
+
"kind": "function",
|
|
1768
|
+
"params": {"p": {"type": "cds.Integer"}},
|
|
1769
|
+
"returns": {"type": "cds.String"}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
},
|
|
1773
|
+
"S": {
|
|
1774
|
+
"kind": "service"
|
|
1775
|
+
},
|
|
1776
|
+
"S.A": {
|
|
1777
|
+
"kind": "action",
|
|
1778
|
+
"params": {"p": {"type": "cds.Integer"}}
|
|
1779
|
+
},
|
|
1780
|
+
"S.F": {
|
|
1781
|
+
"kind": "function",
|
|
1782
|
+
"params": {"p": {"type": "cds.Integer"}},
|
|
1783
|
+
"returns": {"type": "cds.String"}
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
```
|
|
1788
|
+
|
|
1789
|
+
</details>
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
### Associations via backlink
|
|
1793
|
+
|
|
1794
|
+
In CAP CDS, an association from `A` to `B` can be defined based on an association
|
|
1795
|
+
from `B` to `A` via a special ON condition.
|
|
1796
|
+
|
|
1797
|
+
Usually this is used with a managed association:
|
|
1798
|
+
```cds
|
|
1799
|
+
// original CDS source
|
|
1800
|
+
entity Books {
|
|
1801
|
+
key id : Integer;
|
|
1802
|
+
author : Association to one Authors; // backlink association
|
|
1803
|
+
}
|
|
1804
|
+
entity Authors {
|
|
1805
|
+
key id : Integer;
|
|
1806
|
+
books : Association to many Books on books.author = $self; // association via backlink
|
|
1807
|
+
// books.author.id = id // effective ON condition
|
|
1808
|
+
}
|
|
1809
|
+
```
|
|
1810
|
+
|
|
1811
|
+
but also works with an unmanaged association:
|
|
1812
|
+
```cds
|
|
1813
|
+
// original CDS source
|
|
1814
|
+
entity Books {
|
|
1815
|
+
key id : Integer;
|
|
1816
|
+
author_id : Integer;
|
|
1817
|
+
author : Association to one Authors on author.id = author_id;
|
|
1818
|
+
}
|
|
1819
|
+
entity Authors {
|
|
1820
|
+
key id : Integer;
|
|
1821
|
+
books : Association to many Books on books.author = $self; // association via backlink
|
|
1822
|
+
// books.author.id = id // effective ON condition
|
|
1823
|
+
}
|
|
1824
|
+
```
|
|
1825
|
+
|
|
1826
|
+
In Effective CSN, these ON conditions with `$self` are rewritten to ordinary ON conditions,
|
|
1827
|
+
like indicated in the examples.
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
### Calculated Elements
|
|
1831
|
+
|
|
1832
|
+
### $calc
|
|
1833
|
+
|
|
1834
|
+
The compiler adds property `$calc` to those elements of views/projections, which are
|
|
1835
|
+
calculated fields (i.e. have a column expression) or references to
|
|
1836
|
+
a calculated field or element further down the view stack.
|
|
1837
|
+
|
|
1838
|
+
For Effective CSN, `$calc` is removed.
|
|
1839
|
+
|
|
1840
|
+
Example:
|
|
1841
|
+
```cds
|
|
1842
|
+
entity E {
|
|
1843
|
+
key id : Integer;
|
|
1844
|
+
a : Integer;
|
|
1845
|
+
b : Integer;
|
|
1846
|
+
cal : Integer = a + b;
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
view V as select from E {
|
|
1850
|
+
id,
|
|
1851
|
+
a, b,
|
|
1852
|
+
a+b as ab, // has $calc in Inferred CSN
|
|
1853
|
+
cal // has $calc in Inferred CSN
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
view W as select from V {
|
|
1857
|
+
id,
|
|
1858
|
+
a, b,
|
|
1859
|
+
ab, // has $calc in Inferred CSN
|
|
1860
|
+
cal // has $calc in Inferred CSN
|
|
1861
|
+
}
|
|
1862
|
+
```
|
|
1863
|
+
|
|
1864
|
+
<details>
|
|
1865
|
+
<summary>Inferred CSN</summary>
|
|
1866
|
+
|
|
1867
|
+
```jsonc
|
|
1868
|
+
{
|
|
1869
|
+
"definitions": {
|
|
1870
|
+
"E": { /* ... */ },
|
|
1871
|
+
"V": {
|
|
1872
|
+
"kind": "entity",
|
|
1873
|
+
"query": { /* ... */ },
|
|
1874
|
+
"elements": {
|
|
1875
|
+
"id": { "key": true, "type": "cds.Integer" },
|
|
1876
|
+
"a": { "type": "cds.Integer" },
|
|
1877
|
+
"b": { "type": "cds.Integer" },
|
|
1878
|
+
"ab": {
|
|
1879
|
+
"@Core.Computed": true,
|
|
1880
|
+
"$calc": { "xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}] }
|
|
1881
|
+
},
|
|
1882
|
+
"cal": {
|
|
1883
|
+
"@Core.Computed": true,
|
|
1884
|
+
"type": "cds.Integer",
|
|
1885
|
+
"$calc": { "xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}] }
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
},
|
|
1889
|
+
"W": {
|
|
1890
|
+
"kind": "entity",
|
|
1891
|
+
"query": { /* ... */ },
|
|
1892
|
+
"elements": {
|
|
1893
|
+
"id": { "key": true, "type": "cds.Integer" },
|
|
1894
|
+
"a": { "type": "cds.Integer" },
|
|
1895
|
+
"b": { "type": "cds.Integer" },
|
|
1896
|
+
"ab": {
|
|
1897
|
+
"@Core.Computed": true,
|
|
1898
|
+
"$calc": { "xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}] }
|
|
1899
|
+
},
|
|
1900
|
+
"cal": {
|
|
1901
|
+
"@Core.Computed": true,
|
|
1902
|
+
"type": "cds.Integer",
|
|
1903
|
+
"$calc": { "xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}] }
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
```
|
|
1910
|
+
|
|
1911
|
+
</details>
|
|
1912
|
+
|
|
1913
|
+
|
|
1914
|
+
#### Calculated elements on-read
|
|
1915
|
+
|
|
1916
|
+
[Calculated elements](https://cap.cloud.sap/docs/cds/cdl#on-read) are elements
|
|
1917
|
+
in non-query entity that hold an expression. They can be used in views/projections at every place
|
|
1918
|
+
where an expression can occur.
|
|
1919
|
+
|
|
1920
|
+
For Effective CSN, calculated element definitions are removed
|
|
1921
|
+
and each reference to a calculated element is replaced with the respective expression.
|
|
1922
|
+
|
|
1923
|
+
Example:
|
|
1924
|
+
CDS:
|
|
1925
|
+
```cds
|
|
1926
|
+
entity E {
|
|
1927
|
+
key id : Integer;
|
|
1928
|
+
a : Integer;
|
|
1929
|
+
b : Integer;
|
|
1930
|
+
c1 : Integer = a + b;
|
|
1931
|
+
c2 : Integer = 2 * c1; // can be nested
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
view V as select from E {
|
|
1935
|
+
id,
|
|
1936
|
+
c1,
|
|
1937
|
+
4 + c2 as x,
|
|
1938
|
+
c1 + c2 as c3,
|
|
1939
|
+
c1 + 4 as c4,
|
|
1940
|
+
$projection.c4 + 4 as c5
|
|
1941
|
+
};
|
|
1942
|
+
|
|
1943
|
+
view V2 as select from V {
|
|
1944
|
+
id,
|
|
1945
|
+
c1,
|
|
1946
|
+
x,
|
|
1947
|
+
c3
|
|
1948
|
+
};
|
|
1949
|
+
```
|
|
1950
|
+
In the SQL table generated for `E`, the calculated elements are not present.
|
|
1951
|
+
|
|
1952
|
+
<details>
|
|
1953
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
1954
|
+
|
|
1955
|
+
```cds
|
|
1956
|
+
entity E {
|
|
1957
|
+
key id : Integer;
|
|
1958
|
+
a : Integer;
|
|
1959
|
+
b : Integer;
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
view V as select from E {
|
|
1963
|
+
id,
|
|
1964
|
+
a + b as c1 : Integer,
|
|
1965
|
+
4 + (2 * (a + b)) as x : Integer,
|
|
1966
|
+
(a+b) + 2*(a+b) as c3,
|
|
1967
|
+
(a + b) + 4 as c4,
|
|
1968
|
+
$projection.c4 + 4 as c5 // > see section $projection below
|
|
1969
|
+
};
|
|
1970
|
+
|
|
1971
|
+
view V2 as select from E {
|
|
1972
|
+
id,
|
|
1973
|
+
c1,
|
|
1974
|
+
x,
|
|
1975
|
+
c3
|
|
1976
|
+
};
|
|
1977
|
+
```
|
|
1978
|
+
|
|
1979
|
+
</details>
|
|
1980
|
+
|
|
1981
|
+
#### Calculated elements on-write
|
|
1982
|
+
|
|
1983
|
+
No transformation is applied for Effective CSN.
|
|
1984
|
+
|
|
1985
|
+
There is a second flavor of calculated elements, called
|
|
1986
|
+
[Calculated elements on-write](https://cap.cloud.sap/docs/cds/cdl#on-write).
|
|
1987
|
+
|
|
1988
|
+
```cds
|
|
1989
|
+
// original CDS source
|
|
1990
|
+
entity E {
|
|
1991
|
+
key id : Integer;
|
|
1992
|
+
a : Integer;
|
|
1993
|
+
b : Integer;
|
|
1994
|
+
c : Integer = a + b stored;
|
|
1995
|
+
}
|
|
1996
|
+
entity V as select from E {
|
|
1997
|
+
id, c
|
|
1998
|
+
};
|
|
1999
|
+
```
|
|
2000
|
+
|
|
2001
|
+
They are implemented in CAP by using the HANA feature "GENERATED ALWAYS AS".
|
|
2002
|
+
<details>
|
|
2003
|
+
<summary>Resulting SQL</summary>
|
|
2004
|
+
|
|
2005
|
+
```sql
|
|
2006
|
+
create table E (
|
|
2007
|
+
id Integer,
|
|
2008
|
+
a Integer,
|
|
2009
|
+
b Integer,
|
|
2010
|
+
c Integer always generated as (a + b),
|
|
2011
|
+
primary key (id)
|
|
2012
|
+
)
|
|
2013
|
+
```
|
|
2014
|
+
|
|
2015
|
+
</details>
|
|
2016
|
+
|
|
2017
|
+
<br />
|
|
2018
|
+
|
|
2019
|
+
Calculated elements on-write are kept in Effective CSN without any change.
|
|
2020
|
+
Besides the definition, calculated elements on-write behave like regular (read-only) elements,
|
|
2021
|
+
no special treatment or representation is necessary.
|
|
2022
|
+
|
|
2023
|
+
<details>
|
|
2024
|
+
<summary>Effective CSN</summary>
|
|
2025
|
+
|
|
2026
|
+
```json
|
|
2027
|
+
{
|
|
2028
|
+
"definitions": {
|
|
2029
|
+
"E": {
|
|
2030
|
+
"kind": "entity",
|
|
2031
|
+
"elements": {
|
|
2032
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2033
|
+
"a": {"type": "cds.Integer"},
|
|
2034
|
+
"b": {"type": "cds.Integer"},
|
|
2035
|
+
"c": {
|
|
2036
|
+
"@Core.Computed": true,
|
|
2037
|
+
"type": "cds.Integer",
|
|
2038
|
+
"value": { // <
|
|
2039
|
+
"stored": true,
|
|
2040
|
+
"xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}]
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
},
|
|
2045
|
+
"V": {
|
|
2046
|
+
"kind": "entity",
|
|
2047
|
+
"query": {
|
|
2048
|
+
"SELECT": {
|
|
2049
|
+
"from": {"ref": ["E"]},
|
|
2050
|
+
"columns": [
|
|
2051
|
+
{"ref": ["id"]},
|
|
2052
|
+
{"ref": ["c"]}
|
|
2053
|
+
]
|
|
2054
|
+
}
|
|
2055
|
+
},
|
|
2056
|
+
"elements": {
|
|
2057
|
+
"id": { "key": true, "type": "cds.Integer"},
|
|
2058
|
+
"c": {"@Core.Computed": true, "type": "cds.Integer"}
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
```
|
|
2064
|
+
|
|
2065
|
+
</details>
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
### Draft
|
|
2069
|
+
|
|
2070
|
+
Annotations `@odata.draft.enabled` are kept in Effective CSN, but no "draft unfolding" is done.
|
|
2071
|
+
I.e. Effective CSN doesn't contain any draft specific entities (DraftAdministrativeData, `.drafts` entities)
|
|
2072
|
+
or associations.
|
|
2073
|
+
|
|
2074
|
+
|
|
2075
|
+
### Queries
|
|
2076
|
+
|
|
2077
|
+
CDS queries can contain a number of features that may be CAP specific and are not
|
|
2078
|
+
understood generally. In the following sections we define which of them stay in Effective CSN,
|
|
2079
|
+
and which ones are transformed.
|
|
2080
|
+
|
|
2081
|
+
|
|
2082
|
+
### Query: No assoc2join
|
|
2083
|
+
|
|
2084
|
+
No transformation applied for Effective CSN.
|
|
2085
|
+
|
|
2086
|
+
Paths with associations in views/projections are __not__ translated to JOINS, but
|
|
2087
|
+
are left untouched.
|
|
2088
|
+
|
|
2089
|
+
|
|
2090
|
+
### Query: EXISTS paths
|
|
2091
|
+
|
|
2092
|
+
CAP CDS supports a simplified way to formulate EXISTS subqueries.
|
|
2093
|
+
For Effective CSN, we expand EXISTS paths to regular subqueries.
|
|
2094
|
+
|
|
2095
|
+
Example:
|
|
2096
|
+
CDS:
|
|
2097
|
+
```cds
|
|
2098
|
+
entity Books {
|
|
2099
|
+
key id : Integer;
|
|
2100
|
+
price : Decimal;
|
|
2101
|
+
author_id : Integer;
|
|
2102
|
+
}
|
|
2103
|
+
entity Authors {
|
|
2104
|
+
key id : Integer;
|
|
2105
|
+
books : Association to many Books on books.author_id = id;
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
entity AuthorsWithExpensiveBooks as select from Authors {
|
|
2109
|
+
id
|
|
2110
|
+
} where exists books[price > 100.00];
|
|
2111
|
+
```
|
|
2112
|
+
|
|
2113
|
+
<details>
|
|
2114
|
+
<summary>Effective CSN</summary>
|
|
2115
|
+
|
|
2116
|
+
```json
|
|
2117
|
+
{
|
|
2118
|
+
"definitions": {
|
|
2119
|
+
"Books": {
|
|
2120
|
+
"kind": "entity",
|
|
2121
|
+
"elements": {
|
|
2122
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2123
|
+
"price": {"type": "cds.Decimal"},
|
|
2124
|
+
"author_id": {"type": "cds.Integer"}
|
|
2125
|
+
}
|
|
2126
|
+
},
|
|
2127
|
+
"Authors": {
|
|
2128
|
+
"kind": "entity",
|
|
2129
|
+
"elements": {
|
|
2130
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2131
|
+
"books": {
|
|
2132
|
+
"type": "cds.Association",
|
|
2133
|
+
"cardinality": {"max": "*"},
|
|
2134
|
+
"target": "Books",
|
|
2135
|
+
"on": [{"ref": ["books","author_id"]}, "=", {"ref": ["id"]}]
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
},
|
|
2139
|
+
"AuthorsWithExpensiveBooks": {
|
|
2140
|
+
"kind": "entity",
|
|
2141
|
+
"query": {
|
|
2142
|
+
"SELECT": {
|
|
2143
|
+
"from": {"ref": ["Authors"]},
|
|
2144
|
+
"columns": [{"ref": ["id"]}],
|
|
2145
|
+
"where": [
|
|
2146
|
+
"exists",
|
|
2147
|
+
{
|
|
2148
|
+
"SELECT": {
|
|
2149
|
+
"from": {"ref": ["Books"], "as": "_books_exists"},
|
|
2150
|
+
"columns": [{"val": 1, "as": "dummy"}],
|
|
2151
|
+
"where": [
|
|
2152
|
+
{"ref": ["_books_exists","author_id"]}, "=", {"ref": ["Authors","id"]},
|
|
2153
|
+
"and",
|
|
2154
|
+
{"ref": ["_books_exists","price"]}, ">", {"val": "100.0", "literal": "number"}
|
|
2155
|
+
]
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
]
|
|
2159
|
+
}
|
|
2160
|
+
},
|
|
2161
|
+
"elements": {
|
|
2162
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
```
|
|
2168
|
+
|
|
2169
|
+
</details>
|
|
2170
|
+
|
|
2171
|
+
<details>
|
|
2172
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
2173
|
+
|
|
2174
|
+
```cds
|
|
2175
|
+
entity AuthorsWithExpensiveBooks as select from Authors {
|
|
2176
|
+
id
|
|
2177
|
+
} where exists (select 1 as dummy from Books as _books_exists
|
|
2178
|
+
where _books_exists.author_id = Authors.id and _books_exists.price > 100 );
|
|
2179
|
+
```
|
|
2180
|
+
|
|
2181
|
+
</details>
|
|
2182
|
+
|
|
2183
|
+
<br />
|
|
2184
|
+
|
|
2185
|
+
Note:
|
|
2186
|
+
* Exists paths can be nested, resulting in corresponding nested subqueries.
|
|
2187
|
+
* This step doesn't introduce table aliases for the existing data sources (`Authors`).
|
|
2188
|
+
* We currently generate a `SELECT 1 as dummy FROM ...` with an unnecessary alias. The alias may vanish in the future.
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
### Query: CDL style cast
|
|
2193
|
+
|
|
2194
|
+
No transformation applied for Effective CSN.
|
|
2195
|
+
|
|
2196
|
+
CAP CDS doesn't compute result types for expressions. If a type is needed for an expression in a view,
|
|
2197
|
+
e.g. for OData exposure, it can be explicitly set via a "CDL-style cast".
|
|
2198
|
+
For Effective CSN, we keep these CDL style casts.
|
|
2199
|
+
|
|
2200
|
+
Example:
|
|
2201
|
+
CDS:
|
|
2202
|
+
```cds
|
|
2203
|
+
entity E {
|
|
2204
|
+
key id : Integer;
|
|
2205
|
+
r : Integer;
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
view V as select from E {
|
|
2209
|
+
id,
|
|
2210
|
+
2 * 3.1415 * r as area : Decimal(11,4)
|
|
2211
|
+
};
|
|
2212
|
+
```
|
|
2213
|
+
|
|
2214
|
+
<details>
|
|
2215
|
+
<summary>Effective CSN</summary>
|
|
2216
|
+
|
|
2217
|
+
```json
|
|
2218
|
+
{
|
|
2219
|
+
"definitions": {
|
|
2220
|
+
"E": { ... },
|
|
2221
|
+
"V": {
|
|
2222
|
+
"kind": "entity",
|
|
2223
|
+
"query": {
|
|
2224
|
+
"SELECT": {
|
|
2225
|
+
"from": {"ref": ["E"]},
|
|
2226
|
+
"columns": [
|
|
2227
|
+
{"ref": ["id"]},
|
|
2228
|
+
{
|
|
2229
|
+
"xpr": [{"val": 2}, "*", {"val": 3.1415}, "*", {"ref": ["r"]}],
|
|
2230
|
+
"as": "area",
|
|
2231
|
+
"cast": {
|
|
2232
|
+
"type": "cds.Decimal",
|
|
2233
|
+
"precision": 11,
|
|
2234
|
+
"scale": 4
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
]
|
|
2238
|
+
}
|
|
2239
|
+
},
|
|
2240
|
+
"elements": {
|
|
2241
|
+
"id": {"key": true, "type": "cds.Integer"},
|
|
2242
|
+
"area": {"@Core.Computed": true, "type": "cds.Decimal", "precision": 11, "scale": 4}
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
```
|
|
2248
|
+
|
|
2249
|
+
</details>
|
|
2250
|
+
|
|
2251
|
+
|
|
2252
|
+
### Query: $projection
|
|
2253
|
+
|
|
2254
|
+
In the query of a view (or projection), CAP CDS allows to refer to elements of the view's
|
|
2255
|
+
own select list via `$projection` or `$self` (they are equivalent in this case).
|
|
2256
|
+
For Effective CSN, we do __not__ replace such references with the original expression.
|
|
2257
|
+
|
|
2258
|
+
Example:
|
|
2259
|
+
CDS:
|
|
2260
|
+
```cds
|
|
2261
|
+
entity E {
|
|
2262
|
+
key id : Integer;
|
|
2263
|
+
a : Integer;
|
|
2264
|
+
b : Integer;
|
|
2265
|
+
f : Association to F on f.id = b;
|
|
2266
|
+
}
|
|
2267
|
+
entity F {
|
|
2268
|
+
key id : Integer;
|
|
2269
|
+
x : Integer;
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
view V as select from E {
|
|
2273
|
+
id,
|
|
2274
|
+
a + b as c1,
|
|
2275
|
+
a - b as c2,
|
|
2276
|
+
$projection.c1 + $projection.c2 as c3,
|
|
2277
|
+
f.x as p,
|
|
2278
|
+
$self.p as p2
|
|
2279
|
+
} where $projection.c1 > 27;
|
|
2280
|
+
```
|
|
2281
|
+
|
|
2282
|
+
<details>
|
|
2283
|
+
<summary>Effective CSN</summary>
|
|
2284
|
+
|
|
2285
|
+
```json
|
|
2286
|
+
{
|
|
2287
|
+
"definitions": {
|
|
2288
|
+
"E": {... },
|
|
2289
|
+
"F": { ... },
|
|
2290
|
+
"V": {
|
|
2291
|
+
"kind": "entity",
|
|
2292
|
+
"query": {
|
|
2293
|
+
"SELECT": {
|
|
2294
|
+
"from": {"ref": ["E"]},
|
|
2295
|
+
"columns": [
|
|
2296
|
+
{"ref": ["id"]},
|
|
2297
|
+
{"xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}], "as": "c1" },
|
|
2298
|
+
{"xpr": [{"ref": ["a"]}, "-",{"ref": ["b"]}], "as": "c2"},
|
|
2299
|
+
{"xpr": [{"ref": ["$projection","c1"]}, "+", {"ref": ["$projection","c2"]}], "as": "c3"},
|
|
2300
|
+
{"ref": ["f","x"], "as": "p"},
|
|
2301
|
+
{"ref": ["$self","p"], "as": "p2"}
|
|
2302
|
+
],
|
|
2303
|
+
"where": [{"ref": ["$projection","c1"]}, ">", {"val": 27}]
|
|
2304
|
+
}
|
|
2305
|
+
},
|
|
2306
|
+
"elements": {
|
|
2307
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2308
|
+
"c1": {"@Core.Computed": true},
|
|
2309
|
+
"c2": {"@Core.Computed": true},
|
|
2310
|
+
"c3": {"@Core.Computed": true},
|
|
2311
|
+
"p": {"type": "cds.Integer"},
|
|
2312
|
+
"p2": {"type": "cds.Integer"}
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
```
|
|
2318
|
+
|
|
2319
|
+
</details>
|
|
2320
|
+
|
|
2321
|
+
|
|
2322
|
+
### Query: select *
|
|
2323
|
+
|
|
2324
|
+
CAP CDS allows to model queries with `select *`. In Effective CSN, the `*` is expanded to an explicit column list.
|
|
2325
|
+
Reasoning: the `*` is a modelling feature that simplifies writing queries
|
|
2326
|
+
and ensures that in extension scenarios new elements are automatically selected. These benefits are not necessary in
|
|
2327
|
+
an Effective CSN.
|
|
2328
|
+
|
|
2329
|
+
Example:
|
|
2330
|
+
CDS:
|
|
2331
|
+
```cds
|
|
2332
|
+
entity E {
|
|
2333
|
+
key id : Integer;
|
|
2334
|
+
a : Integer;
|
|
2335
|
+
b : Integer;
|
|
2336
|
+
}
|
|
2337
|
+
entity V1 as select from E;
|
|
2338
|
+
entity V2 as select from E { * };
|
|
2339
|
+
entity V3 as select from E { *, 7 as a}; // "smart *"
|
|
2340
|
+
entity V4 as select from E { * } excluding { b };
|
|
2341
|
+
```
|
|
2342
|
+
|
|
2343
|
+
<details>
|
|
2344
|
+
<summary>Effective CSN</summary>
|
|
2345
|
+
|
|
2346
|
+
```json
|
|
2347
|
+
{
|
|
2348
|
+
"definitions": {
|
|
2349
|
+
"E": { ... },
|
|
2350
|
+
"V1": {
|
|
2351
|
+
"kind": "entity",
|
|
2352
|
+
"query": {
|
|
2353
|
+
"SELECT": {
|
|
2354
|
+
"from": {"ref": ["E"]},
|
|
2355
|
+
"columns": [
|
|
2356
|
+
{"ref": ["id"]},
|
|
2357
|
+
{"ref": ["a"]},
|
|
2358
|
+
{"ref": ["b"]}
|
|
2359
|
+
]
|
|
2360
|
+
}
|
|
2361
|
+
},
|
|
2362
|
+
"elements": {
|
|
2363
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2364
|
+
"a": {"type": "cds.Integer"},
|
|
2365
|
+
"b": {"type": "cds.Integer"}
|
|
2366
|
+
}
|
|
2367
|
+
},
|
|
2368
|
+
"V2": {
|
|
2369
|
+
"kind": "entity",
|
|
2370
|
+
"query": {
|
|
2371
|
+
"SELECT": {
|
|
2372
|
+
"from": {"ref": ["E"]},
|
|
2373
|
+
"columns": [
|
|
2374
|
+
{"ref": ["id"]},
|
|
2375
|
+
{"ref": ["a"]},
|
|
2376
|
+
{"ref": ["b"]}
|
|
2377
|
+
]
|
|
2378
|
+
}
|
|
2379
|
+
},
|
|
2380
|
+
"elements": {
|
|
2381
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2382
|
+
"a": {"type": "cds.Integer"},
|
|
2383
|
+
"b": {"type": "cds.Integer"}
|
|
2384
|
+
}
|
|
2385
|
+
},
|
|
2386
|
+
"V3": {
|
|
2387
|
+
"kind": "entity",
|
|
2388
|
+
"query": {
|
|
2389
|
+
"SELECT": {
|
|
2390
|
+
"from": {"ref": ["E"]},
|
|
2391
|
+
"columns": [
|
|
2392
|
+
{"ref": ["id"]},
|
|
2393
|
+
{"val": 7,"as": "a"},
|
|
2394
|
+
{"ref": ["b"]}
|
|
2395
|
+
]
|
|
2396
|
+
}
|
|
2397
|
+
},
|
|
2398
|
+
"elements": {
|
|
2399
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2400
|
+
"a": {"@Core.Computed": true},
|
|
2401
|
+
"b": {"type": "cds.Integer"}
|
|
2402
|
+
}
|
|
2403
|
+
},
|
|
2404
|
+
"V4": {
|
|
2405
|
+
"kind": "entity",
|
|
2406
|
+
"query": {
|
|
2407
|
+
"SELECT": {
|
|
2408
|
+
"from": {"ref": ["E"]},
|
|
2409
|
+
"columns": [
|
|
2410
|
+
{"ref": ["id"]},
|
|
2411
|
+
{"ref": ["a"]}
|
|
2412
|
+
]
|
|
2413
|
+
}
|
|
2414
|
+
},
|
|
2415
|
+
"elements": {
|
|
2416
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2417
|
+
"a": {"type": "cds.Integer"}
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
```
|
|
2423
|
+
|
|
2424
|
+
</details>
|
|
2425
|
+
|
|
2426
|
+
<details>
|
|
2427
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
2428
|
+
|
|
2429
|
+
```cds
|
|
2430
|
+
entity E {...};
|
|
2431
|
+
entity V1 as select from E { id, a, b};
|
|
2432
|
+
entity V2 as select from E { id, a, b };
|
|
2433
|
+
entity V3 as select from E { id, 7 as a, b};
|
|
2434
|
+
entity V4 as select from E { id, a };
|
|
2435
|
+
```
|
|
2436
|
+
|
|
2437
|
+
</details>
|
|
2438
|
+
|
|
2439
|
+
|
|
2440
|
+
### Query: filter
|
|
2441
|
+
|
|
2442
|
+
Paths with associations may have an infix filter.
|
|
2443
|
+
We keep them in the Effective CSN.
|
|
2444
|
+
|
|
2445
|
+
|
|
2446
|
+
Example:
|
|
2447
|
+
CDS:
|
|
2448
|
+
```cds
|
|
2449
|
+
entity Teams {
|
|
2450
|
+
key id : Integer;
|
|
2451
|
+
members : Association to many TeamMembers on members.team = $self;
|
|
2452
|
+
}
|
|
2453
|
+
entity TeamMembers {
|
|
2454
|
+
key id : Integer;
|
|
2455
|
+
team : Association to Teams;
|
|
2456
|
+
name : String;
|
|
2457
|
+
isLead : Boolean;
|
|
2458
|
+
projects : Integer;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
entity V as select from Teams {
|
|
2462
|
+
id,
|
|
2463
|
+
members[projects = 0].name as withoutProject,
|
|
2464
|
+
members[1: isLead = true].name as teamLead
|
|
2465
|
+
};
|
|
2466
|
+
```
|
|
2467
|
+
|
|
2468
|
+
<details>
|
|
2469
|
+
<summary>Effective CSN</summary>
|
|
2470
|
+
|
|
2471
|
+
```json
|
|
2472
|
+
{
|
|
2473
|
+
"definitions": {
|
|
2474
|
+
"Teams": { ... },
|
|
2475
|
+
"TeamMembers": { ... },
|
|
2476
|
+
"V": {
|
|
2477
|
+
"kind": "entity",
|
|
2478
|
+
"query": {
|
|
2479
|
+
"SELECT": {
|
|
2480
|
+
"from": {"ref": ["Teams"]},
|
|
2481
|
+
"columns": [
|
|
2482
|
+
{"ref": ["id"]},
|
|
2483
|
+
{
|
|
2484
|
+
"ref": [
|
|
2485
|
+
{
|
|
2486
|
+
"id": "members",
|
|
2487
|
+
"where": [{"ref": ["projects"]}, "=", {"val": 0}]
|
|
2488
|
+
},
|
|
2489
|
+
"name"
|
|
2490
|
+
],
|
|
2491
|
+
"as": "withoutProject"
|
|
2492
|
+
},
|
|
2493
|
+
{
|
|
2494
|
+
"ref": [
|
|
2495
|
+
{
|
|
2496
|
+
"id": "members",
|
|
2497
|
+
"cardinality": {"max": 1},
|
|
2498
|
+
"where": [{"ref": ["isLead"]}, "=", {"val": true}]
|
|
2499
|
+
},
|
|
2500
|
+
"name"
|
|
2501
|
+
],
|
|
2502
|
+
"as": "teamLead"
|
|
2503
|
+
}
|
|
2504
|
+
]
|
|
2505
|
+
}
|
|
2506
|
+
},
|
|
2507
|
+
"elements": {
|
|
2508
|
+
"id": {"type": "cds.Integer"},
|
|
2509
|
+
"withoutProject": {"type": "cds.String"},
|
|
2510
|
+
"teamLead": {"type": "cds.String"}
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
```
|
|
2516
|
+
|
|
2517
|
+
</details>
|
|
2518
|
+
|
|
2519
|
+
|
|
2520
|
+
### Query: expand and inline
|
|
2521
|
+
|
|
2522
|
+
#### Nested inline
|
|
2523
|
+
|
|
2524
|
+
CAP CDS supports a syntax convenience feature [Nested inline](https://cap.cloud.sap/docs/cds/cql#nested-inlines).
|
|
2525
|
+
Paths in the select list that share a common prefix can be grouped.
|
|
2526
|
+
|
|
2527
|
+
Example:
|
|
2528
|
+
```cds
|
|
2529
|
+
entity E {
|
|
2530
|
+
key id : Integer;
|
|
2531
|
+
a : Integer;
|
|
2532
|
+
f : Association to F on f.id = a;
|
|
2533
|
+
}
|
|
2534
|
+
entity F {
|
|
2535
|
+
key id : Integer;
|
|
2536
|
+
x : Integer;
|
|
2537
|
+
y : Integer;
|
|
2538
|
+
}
|
|
2539
|
+
entity V_inline as select from E {
|
|
2540
|
+
id,
|
|
2541
|
+
f.{ x, y }
|
|
2542
|
+
};
|
|
2543
|
+
```
|
|
2544
|
+
|
|
2545
|
+
The view definition above is equivalent to
|
|
2546
|
+
```cds
|
|
2547
|
+
entity V_inline as select from E {
|
|
2548
|
+
id,
|
|
2549
|
+
f.x,
|
|
2550
|
+
f.y
|
|
2551
|
+
};
|
|
2552
|
+
```
|
|
2553
|
+
Effective CSN contains this unfolded form.
|
|
2554
|
+
|
|
2555
|
+
<details>
|
|
2556
|
+
<summary>Effective CSN</summary>
|
|
2557
|
+
|
|
2558
|
+
```json
|
|
2559
|
+
{
|
|
2560
|
+
"definitions": {
|
|
2561
|
+
"E": { ... },
|
|
2562
|
+
"F": { ... },
|
|
2563
|
+
"V_inline": {
|
|
2564
|
+
"kind": "entity",
|
|
2565
|
+
"query": {
|
|
2566
|
+
"SELECT": {
|
|
2567
|
+
"from": {"ref": ["E"]},
|
|
2568
|
+
"columns": [
|
|
2569
|
+
{"ref": ["id"]},
|
|
2570
|
+
{"ref": ["f","x"]},
|
|
2571
|
+
{"ref": ["f","y"]}
|
|
2572
|
+
]
|
|
2573
|
+
}
|
|
2574
|
+
},
|
|
2575
|
+
"elements": {
|
|
2576
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2577
|
+
"x": {"type": "cds.Integer"},
|
|
2578
|
+
"y": {"type": "cds.Integer"}
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
```
|
|
2584
|
+
</details>
|
|
2585
|
+
|
|
2586
|
+
#### Nested expand
|
|
2587
|
+
|
|
2588
|
+
CAP CDS also supports [Nested expand](https://cap.cloud.sap/docs/cds/cql#nested-expands).
|
|
2589
|
+
This is not only a syntax shortcut, but allows to "create" structured result sets.
|
|
2590
|
+
|
|
2591
|
+
Example:
|
|
2592
|
+
```cds
|
|
2593
|
+
entity V_expand as select from E {
|
|
2594
|
+
id,
|
|
2595
|
+
f { x, y }
|
|
2596
|
+
};
|
|
2597
|
+
```
|
|
2598
|
+
|
|
2599
|
+
Here the resulting `V_expand` contains a structured element `f` with elements `x` and `y`,
|
|
2600
|
+
which is flattened in Effective CSN.
|
|
2601
|
+
|
|
2602
|
+
<details>
|
|
2603
|
+
<summary>Effective CSN</summary>
|
|
2604
|
+
|
|
2605
|
+
```json
|
|
2606
|
+
{
|
|
2607
|
+
"definitions": {
|
|
2608
|
+
"E": { ... },
|
|
2609
|
+
"F": { ... },
|
|
2610
|
+
"V_expand": {
|
|
2611
|
+
"kind": "entity",
|
|
2612
|
+
"query": {
|
|
2613
|
+
"SELECT": {
|
|
2614
|
+
"from": {"ref": ["E"]},
|
|
2615
|
+
"columns": [
|
|
2616
|
+
{"ref": ["id"]},
|
|
2617
|
+
{"ref": ["f","x"], "as": "f_x"},
|
|
2618
|
+
{"ref": ["f","y"], "as": "f_y"}
|
|
2619
|
+
]
|
|
2620
|
+
}
|
|
2621
|
+
},
|
|
2622
|
+
"elements": {
|
|
2623
|
+
"id": {"key": true, "type": "cds.Integer"},
|
|
2624
|
+
"f_x": {"type": "cds.Integer"},
|
|
2625
|
+
"f_y": {"type": "cds.Integer"}
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
```
|
|
2631
|
+
</details>
|
|
2632
|
+
|
|
2633
|
+
<details>
|
|
2634
|
+
<summary>CDS source equivalent to Effective CSN</summary>
|
|
2635
|
+
|
|
2636
|
+
```cds
|
|
2637
|
+
entity V_expand as select from E {
|
|
2638
|
+
id,
|
|
2639
|
+
f.x as f_x,
|
|
2640
|
+
f.y as f_y
|
|
2641
|
+
};
|
|
2642
|
+
```
|
|
2643
|
+
</details>
|
|
2644
|
+
|
|
2645
|
+
|
|
2646
|
+
### Query: path in FROM
|
|
2647
|
+
|
|
2648
|
+
CAP CDS supports paths in the FROM clause. For SQL, they are translated to INNER JOIN in the compiler
|
|
2649
|
+
or to a Subquery in the Nodejs runtime, respectively (difference between INNER JOIN and Subquery
|
|
2650
|
+
is that with inner join the same entry of the final target entry may be returned several times while
|
|
2651
|
+
with Subquery they are guaranteed to be unique).
|
|
2652
|
+
|
|
2653
|
+
Paths in FROM are kept in Effective CSN.
|
|
2654
|
+
|
|
2655
|
+
|
|
2656
|
+
Example:
|
|
2657
|
+
```cds
|
|
2658
|
+
entity C.E {
|
|
2659
|
+
key id : Integer;
|
|
2660
|
+
a : Integer;
|
|
2661
|
+
f : Association to C.F on f.id = a;
|
|
2662
|
+
}
|
|
2663
|
+
entity C.F {
|
|
2664
|
+
key id : Integer;
|
|
2665
|
+
b : Integer;
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
entity V as select from C.E:f {
|
|
2669
|
+
id,
|
|
2670
|
+
b
|
|
2671
|
+
};
|
|
2672
|
+
```
|
|
2673
|
+
|
|
2674
|
+
<details>
|
|
2675
|
+
<summary>Effective CSN</summary>
|
|
2676
|
+
|
|
2677
|
+
```json
|
|
2678
|
+
{
|
|
2679
|
+
"definitions": {
|
|
2680
|
+
"C.E": { ... },
|
|
2681
|
+
"C.F": { ... },
|
|
2682
|
+
"V": {
|
|
2683
|
+
"kind": "entity",
|
|
2684
|
+
"query": {
|
|
2685
|
+
"SELECT": {
|
|
2686
|
+
"from": {"ref": ["C.E","f"]},
|
|
2687
|
+
"columns": [
|
|
2688
|
+
{"ref": ["id"]},
|
|
2689
|
+
{"ref": ["b"]}
|
|
2690
|
+
]
|
|
2691
|
+
}
|
|
2692
|
+
},
|
|
2693
|
+
"elements": {
|
|
2694
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2695
|
+
"b": {"type": "cds.Integer"}
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
```
|
|
2701
|
+
</details>
|
|
2702
|
+
|
|
2703
|
+
|
|
2704
|
+
### Query: path in WHERE, GROUP BY
|
|
2705
|
+
|
|
2706
|
+
CAP CDS supports paths in WHERE and GROUP BY.
|
|
2707
|
+
We keep them in the CSN.
|
|
2708
|
+
|
|
2709
|
+
```cds
|
|
2710
|
+
entity V2 as select from E {
|
|
2711
|
+
id,
|
|
2712
|
+
f.b
|
|
2713
|
+
} where f.b = 1 group by f.b;
|
|
2714
|
+
```
|
|
2715
|
+
|
|
2716
|
+
Note: it is not possible to translate these paths to JOINs while not translating
|
|
2717
|
+
paths in the select list.
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
### Query: Projection vs View
|
|
2721
|
+
|
|
2722
|
+
CAP CDS has projections and views. Semantically the difference is that in projections
|
|
2723
|
+
you cannot use explicit joins, unions, or subqueries.
|
|
2724
|
+
|
|
2725
|
+
```cds
|
|
2726
|
+
entity E {
|
|
2727
|
+
key id : Integer;
|
|
2728
|
+
}
|
|
2729
|
+
entity V as select from E { id };
|
|
2730
|
+
entity P as projection on E { id };
|
|
2731
|
+
```
|
|
2732
|
+
|
|
2733
|
+
<details>
|
|
2734
|
+
<summary>Inferred CSN</summary>
|
|
2735
|
+
|
|
2736
|
+
```
|
|
2737
|
+
{
|
|
2738
|
+
"definitions": {
|
|
2739
|
+
"E": { ... },
|
|
2740
|
+
"V": {
|
|
2741
|
+
"kind": "entity",
|
|
2742
|
+
"query": {
|
|
2743
|
+
"SELECT": {
|
|
2744
|
+
"from": {"ref": ["E"]},
|
|
2745
|
+
"columns": [{"ref": ["id"]}]
|
|
2746
|
+
}
|
|
2747
|
+
},
|
|
2748
|
+
"elements": {
|
|
2749
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
2750
|
+
}
|
|
2751
|
+
},
|
|
2752
|
+
"P": {
|
|
2753
|
+
"kind": "entity",
|
|
2754
|
+
"projection": {
|
|
2755
|
+
"from": {"ref": ["E"]},
|
|
2756
|
+
"columns": [{"ref": ["id"]}]
|
|
2757
|
+
},
|
|
2758
|
+
"elements": {
|
|
2759
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
```
|
|
2765
|
+
</details>
|
|
2766
|
+
|
|
2767
|
+
For Effective CSN, the default behavior is to convert projections to views, i.e. we replace `projection` by `query.SELECT`.
|
|
2768
|
+
|
|
2769
|
+
<details>
|
|
2770
|
+
<summary>Effective CSN</summary>
|
|
2771
|
+
|
|
2772
|
+
```
|
|
2773
|
+
{
|
|
2774
|
+
"definitions": {
|
|
2775
|
+
"E": { ... },
|
|
2776
|
+
"V": {
|
|
2777
|
+
"kind": "entity",
|
|
2778
|
+
"query": {
|
|
2779
|
+
"SELECT": {
|
|
2780
|
+
"from": {"ref": ["E"]},
|
|
2781
|
+
"columns": [{"ref": ["id"]}]
|
|
2782
|
+
}
|
|
2783
|
+
},
|
|
2784
|
+
"elements": {
|
|
2785
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
2786
|
+
}
|
|
2787
|
+
},
|
|
2788
|
+
"P": {
|
|
2789
|
+
"kind": "entity",
|
|
2790
|
+
"query": {
|
|
2791
|
+
"SELECT": {
|
|
2792
|
+
"from": {"ref": ["E"]},
|
|
2793
|
+
"columns": [{"ref": ["id"]}]
|
|
2794
|
+
}
|
|
2795
|
+
},
|
|
2796
|
+
"elements": {
|
|
2797
|
+
"id": {"key": true,"type": "cds.Integer"}
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
```
|
|
2803
|
+
</details>
|
|
2804
|
+
|
|
2805
|
+
When option `resolveProjections` is set to `false` (default is `true`), no transformation is applied,
|
|
2806
|
+
i.e. property `projection` is kept as is.
|
|
2807
|
+
|
|
2808
|
+
|
|
2809
|
+
### Query: Mixin associations
|
|
2810
|
+
|
|
2811
|
+
No transformation is applied for Effective CSN.
|
|
2812
|
+
|
|
2813
|
+
CAP CDS allows to define mixin associations. They can be used in the query or be published.
|
|
2814
|
+
|
|
2815
|
+
```cds
|
|
2816
|
+
entity E {
|
|
2817
|
+
key id : Integer;
|
|
2818
|
+
a : Integer;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
entity F {
|
|
2822
|
+
key id : Integer;
|
|
2823
|
+
x : Integer;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
entity V1 as select from E
|
|
2827
|
+
mixin {
|
|
2828
|
+
f : Association to F on f.id = a;
|
|
2829
|
+
} into {
|
|
2830
|
+
a as pa,
|
|
2831
|
+
f.x,
|
|
2832
|
+
f
|
|
2833
|
+
};
|
|
2834
|
+
|
|
2835
|
+
entity V2 as select from E
|
|
2836
|
+
mixin {
|
|
2837
|
+
f : Association to F on f.id = $projection.pa;
|
|
2838
|
+
} into {
|
|
2839
|
+
a as pa,
|
|
2840
|
+
f.x,
|
|
2841
|
+
f
|
|
2842
|
+
};
|
|
2843
|
+
```
|
|
2844
|
+
|
|
2845
|
+
In the definition of a mixin association, you can use elements of the datasource (example: `V1`)
|
|
2846
|
+
or elements of the select list via `$projection` (example: `V2`).
|
|
2847
|
+
|
|
2848
|
+
A mixin association that uses elements of the datasource in its ON condition (example: `V1`)
|
|
2849
|
+
can be used (in a path expression) in the query, or it can be published if all elements used
|
|
2850
|
+
in the ON condition are published, too.
|
|
2851
|
+
|
|
2852
|
+
A mixin association that uses elements of the select list via `$projection` in its ON condition (example: `V2`)
|
|
2853
|
+
can be used (in a path expression) in the query, or it can be published.
|
|
2854
|
+
|
|
2855
|
+
We keep mixin associations in the CSN as is. No transformation is applied
|
|
2856
|
+
|
|
2857
|
+
<details>
|
|
2858
|
+
<summary>Effective CSN</summary>
|
|
2859
|
+
|
|
2860
|
+
```json
|
|
2861
|
+
{
|
|
2862
|
+
"definitions": {
|
|
2863
|
+
"E": { ... },
|
|
2864
|
+
"F": { ... },
|
|
2865
|
+
"V1": {
|
|
2866
|
+
"kind": "entity",
|
|
2867
|
+
"query": {
|
|
2868
|
+
"SELECT": {
|
|
2869
|
+
"from": {"ref": ["E"]},
|
|
2870
|
+
"mixin": {
|
|
2871
|
+
"f": {
|
|
2872
|
+
"type": "cds.Association",
|
|
2873
|
+
"target": "F",
|
|
2874
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["a"]}]
|
|
2875
|
+
}
|
|
2876
|
+
},
|
|
2877
|
+
"columns": [
|
|
2878
|
+
{"ref": ["a"], "as": "pa"},
|
|
2879
|
+
{"ref": ["f","x"]},
|
|
2880
|
+
{"ref": ["f"]}
|
|
2881
|
+
]
|
|
2882
|
+
}
|
|
2883
|
+
},
|
|
2884
|
+
"elements": {
|
|
2885
|
+
"pa": {"type": "cds.Integer"},
|
|
2886
|
+
"x": {"type": "cds.Integer"},
|
|
2887
|
+
"f": {
|
|
2888
|
+
"type": "cds.Association",
|
|
2889
|
+
"target": "F",
|
|
2890
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["pa"]}]
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
},
|
|
2894
|
+
"V2": {
|
|
2895
|
+
"kind": "entity",
|
|
2896
|
+
"query": {
|
|
2897
|
+
"SELECT": {
|
|
2898
|
+
"from": {"ref": ["E"]},
|
|
2899
|
+
"mixin": {
|
|
2900
|
+
"f": {
|
|
2901
|
+
"type": "cds.Association",
|
|
2902
|
+
"target": "F",
|
|
2903
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["$projection","pa"]}]
|
|
2904
|
+
}
|
|
2905
|
+
},
|
|
2906
|
+
"columns": [
|
|
2907
|
+
{"ref": ["a"], "as": "pa"},
|
|
2908
|
+
{"ref": ["f","x"]},
|
|
2909
|
+
{"ref": ["f"]}
|
|
2910
|
+
]
|
|
2911
|
+
}
|
|
2912
|
+
},
|
|
2913
|
+
"elements": {
|
|
2914
|
+
"pa": {"type": "cds.Integer"},
|
|
2915
|
+
"x": {"type": "cds.Integer"},
|
|
2916
|
+
"f": {
|
|
2917
|
+
"type": "cds.Association",
|
|
2918
|
+
"target": "F",
|
|
2919
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["$self","pa"]}]
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
```
|
|
2926
|
+
</details>
|
|
2927
|
+
|
|
2928
|
+
|
|
2929
|
+
### Query: Redirect
|
|
2930
|
+
|
|
2931
|
+
No transformation is applied for Effective CSN.
|
|
2932
|
+
|
|
2933
|
+
CAP CDS allows to explicitly redirect an association that is published in a view:
|
|
2934
|
+
|
|
2935
|
+
```cds
|
|
2936
|
+
entity E {
|
|
2937
|
+
key id : Integer;
|
|
2938
|
+
a : Integer;
|
|
2939
|
+
b : Integer;
|
|
2940
|
+
f : Association to F on f.x = a;
|
|
2941
|
+
}
|
|
2942
|
+
entity F {
|
|
2943
|
+
key id : Integer;
|
|
2944
|
+
x : Integer;
|
|
2945
|
+
y : Integer;
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
view VE as select from E {
|
|
2949
|
+
id, a, b,
|
|
2950
|
+
f as vf1 : redirected to VF,
|
|
2951
|
+
f as vf2 : redirected to VF on vf2.y = b
|
|
2952
|
+
};
|
|
2953
|
+
view VF as select from F {
|
|
2954
|
+
id, x, y
|
|
2955
|
+
};
|
|
2956
|
+
```
|
|
2957
|
+
|
|
2958
|
+
Redirects are kept in Effective CSN without change, no transformation is applied.
|
|
2959
|
+
The redirections are represented as attribute `cast` in the columns.
|
|
2960
|
+
|
|
2961
|
+
<details>
|
|
2962
|
+
<summary>Effective CSN</summary>
|
|
2963
|
+
|
|
2964
|
+
```json
|
|
2965
|
+
{
|
|
2966
|
+
"definitions": {
|
|
2967
|
+
"E": { ... },
|
|
2968
|
+
"F": { ... },
|
|
2969
|
+
"VE": {
|
|
2970
|
+
"kind": "entity",
|
|
2971
|
+
"query": {
|
|
2972
|
+
"SELECT": {
|
|
2973
|
+
"from": {"ref": ["E"]},
|
|
2974
|
+
"columns": [
|
|
2975
|
+
{"ref": ["id"]},
|
|
2976
|
+
{"ref": ["a"]},
|
|
2977
|
+
{"ref": ["b"]},
|
|
2978
|
+
{
|
|
2979
|
+
"ref": ["f"],
|
|
2980
|
+
"as": "vf1",
|
|
2981
|
+
"cast": {
|
|
2982
|
+
"target": "VF"
|
|
2983
|
+
}
|
|
2984
|
+
},
|
|
2985
|
+
{
|
|
2986
|
+
"ref": ["f"],
|
|
2987
|
+
"as": "vf2",
|
|
2988
|
+
"cast": {
|
|
2989
|
+
"target": "VF",
|
|
2990
|
+
"on": [{"ref": ["vf2","y"]}, "=", {"ref": ["b"]}]
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
]
|
|
2994
|
+
}
|
|
2995
|
+
},
|
|
2996
|
+
"elements": {
|
|
2997
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
2998
|
+
"a": {"type": "cds.Integer"},
|
|
2999
|
+
"b": {"type": "cds.Integer"},
|
|
3000
|
+
"vf1": {
|
|
3001
|
+
"type": "cds.Association",
|
|
3002
|
+
"target": "VF",
|
|
3003
|
+
"on": [{"ref": ["vf1","x"]}, "=", {"ref": ["a"]}]
|
|
3004
|
+
},
|
|
3005
|
+
"vf2": {
|
|
3006
|
+
"type": "cds.Association",
|
|
3007
|
+
"target": "VF",
|
|
3008
|
+
"on": [{"ref": ["vf2","y"]}, "=", {"ref": ["b"]}]
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
},
|
|
3012
|
+
"VF": { ... }
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
```
|
|
3016
|
+
</details>
|
|
3017
|
+
|
|
3018
|
+
|
|
3019
|
+
### Query: Defining associations in the select list
|
|
3020
|
+
|
|
3021
|
+
No transformation is applied for Effective CSN.
|
|
3022
|
+
|
|
3023
|
+
CAP CDS supports an easy way to define and publish an unmanaged association in a view or projection.
|
|
3024
|
+
|
|
3025
|
+
```cds
|
|
3026
|
+
entity E {
|
|
3027
|
+
key id : Integer;
|
|
3028
|
+
a : Integer;
|
|
3029
|
+
}
|
|
3030
|
+
entity F {
|
|
3031
|
+
key id : Integer;
|
|
3032
|
+
}
|
|
3033
|
+
|
|
3034
|
+
entity V as select from E {
|
|
3035
|
+
id,
|
|
3036
|
+
a,
|
|
3037
|
+
toF : Association to F on toF.id = a
|
|
3038
|
+
};
|
|
3039
|
+
```
|
|
3040
|
+
|
|
3041
|
+
This is kept in Effective CSN unchanged, no transformation is applied.
|
|
3042
|
+
|
|
3043
|
+
<details>
|
|
3044
|
+
<summary>Effective CSN</summary>
|
|
3045
|
+
|
|
3046
|
+
```json
|
|
3047
|
+
{
|
|
3048
|
+
"definitions": {
|
|
3049
|
+
"E": { ... },
|
|
3050
|
+
"F": { ... },
|
|
3051
|
+
"V": {
|
|
3052
|
+
"kind": "entity",
|
|
3053
|
+
"query": {
|
|
3054
|
+
"SELECT": {
|
|
3055
|
+
"from": {"ref": ["E"]},
|
|
3056
|
+
"columns": [
|
|
3057
|
+
{"ref": ["id"]},
|
|
3058
|
+
{"ref": ["a"]},
|
|
3059
|
+
{
|
|
3060
|
+
"as": "toF",
|
|
3061
|
+
"cast": {
|
|
3062
|
+
"target": "F",
|
|
3063
|
+
"type": "cds.Association",
|
|
3064
|
+
"on": [{"ref": ["toF","id"]}, "=", {"ref": ["a"]}]
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
]
|
|
3068
|
+
}
|
|
3069
|
+
},
|
|
3070
|
+
"elements": {
|
|
3071
|
+
"id": {"key": true,"type": "cds.Integer"},
|
|
3072
|
+
"a": {"type": "cds.Integer"},
|
|
3073
|
+
"toF": {
|
|
3074
|
+
"type": "cds.Association",
|
|
3075
|
+
"target": "F",
|
|
3076
|
+
"on": [{"ref": ["toF","id"]}, "=", {"ref": ["a"]}]
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
```
|
|
3083
|
+
</details>
|
|
3084
|
+
|
|
3085
|
+
|
|
3086
|
+
### Query: Exposing associations
|
|
3087
|
+
|
|
3088
|
+
Exposing managed association is covered above in section "Resolve Managed Associations".
|
|
3089
|
+
Exposing mixin associations is covered above in the section on mixin associations.
|
|
3090
|
+
|
|
3091
|
+
Publishing associations that are defined in a data source of a view or projection should
|
|
3092
|
+
__not__ be turned into definition and publication of a mixin association.
|
|
3093
|
+
|
|
3094
|
+
|
|
3095
|
+
|
|
3096
|
+
### Annotations
|
|
3097
|
+
|
|
3098
|
+
Annotations are kept in Effective CSN as they come from Inferred CSN.
|
|
3099
|
+
No transformations are applied, except:
|
|
3100
|
+
* Annotation expressions: see section below.
|
|
3101
|
+
* For `@cds.persistence.exists/skip/table`, value `'if-unused'` is mapped to `false`.
|
|
3102
|
+
|
|
3103
|
+
|
|
3104
|
+
#### Annotation expressions
|
|
3105
|
+
|
|
3106
|
+
References inside annotation expressions are consistently rewritten, when transformations
|
|
3107
|
+
[Flatten structured types](#flatten-structured-types) and
|
|
3108
|
+
[Resolve Managed Associations](#resolve-managed-associations) are applied.
|
|
3109
|
+
For reference-like annotation expressions, `=` is handled like in Inferred CSN:
|
|
3110
|
+
* For simple references (no filter, no parameters), `=` is the string representation of the reference.
|
|
3111
|
+
* For non-simple references, `=` is `true` (for cds-compiler v6 and lower, sometimes `=` contains the string
|
|
3112
|
+
represenation of the reference).
|
|
3113
|
+
|
|
3114
|
+
Outside of CAP, annotation expressions are not yet known, but that may change.
|
|
3115
|
+
Thus we keep annotation expressions in effective CSN by default, but offer an option
|
|
3116
|
+
to remove them. When option `stringifyAnnoXpr` is set to `true`, annotation expressions are replaced
|
|
3117
|
+
in the following way:
|
|
3118
|
+
|
|
3119
|
+
* Simple references still are an object with a single property `=`
|
|
3120
|
+
(like before introducing annotation expressions).
|
|
3121
|
+
* Enums are kept unchanged.
|
|
3122
|
+
* For all other expressions: the object-like annotation value is replaced by a string representation
|
|
3123
|
+
of the expression.
|
|
3124
|
+
|
|
3125
|
+
Example:
|
|
3126
|
+
```cds
|
|
3127
|
+
@X_ref_simple: (a)
|
|
3128
|
+
@X_ref_nonsimple: (f[id>1].id)
|
|
3129
|
+
@X_xpr: (a+b)
|
|
3130
|
+
@X_enum: (#FOOL)
|
|
3131
|
+
@X_val: (33)
|
|
3132
|
+
@X_func: (coalesce(a, 0))
|
|
3133
|
+
@X_list: ((1, 2, 3))
|
|
3134
|
+
entity E {
|
|
3135
|
+
key id : Integer;
|
|
3136
|
+
a : Integer;
|
|
3137
|
+
b : Integer;
|
|
3138
|
+
f : Association to F;
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
entity F {
|
|
3142
|
+
key id : Integer;
|
|
3143
|
+
}
|
|
3144
|
+
```
|
|
3145
|
+
|
|
3146
|
+
|
|
3147
|
+
<details>
|
|
3148
|
+
<summary>Effective CSN</summary>
|
|
3149
|
+
|
|
3150
|
+
```json
|
|
3151
|
+
{
|
|
3152
|
+
"definitions": {
|
|
3153
|
+
"E": {
|
|
3154
|
+
"kind": "entity",
|
|
3155
|
+
"@X_ref_simple": {
|
|
3156
|
+
"=": "a",
|
|
3157
|
+
"ref": ["a"]
|
|
3158
|
+
},
|
|
3159
|
+
"@X_ref_nonsimple": {
|
|
3160
|
+
"=": true,
|
|
3161
|
+
"ref": [
|
|
3162
|
+
{
|
|
3163
|
+
"id": "f",
|
|
3164
|
+
"where": [{"ref": ["id"]}, ">", {"val": 1}]
|
|
3165
|
+
},
|
|
3166
|
+
"id"
|
|
3167
|
+
]
|
|
3168
|
+
},
|
|
3169
|
+
"@X_xpr": {
|
|
3170
|
+
"xpr": [{"ref": ["a"]}, "+", {"ref": ["b"]}]
|
|
3171
|
+
},
|
|
3172
|
+
"@X_enum": {
|
|
3173
|
+
"#": "FOOL"
|
|
3174
|
+
},
|
|
3175
|
+
"@X_val": {
|
|
3176
|
+
"=": true,
|
|
3177
|
+
"val": 33
|
|
3178
|
+
},
|
|
3179
|
+
"@X_func": {
|
|
3180
|
+
"=": true,
|
|
3181
|
+
"func": "coalesce",
|
|
3182
|
+
"args": [
|
|
3183
|
+
{"ref": [ "a" ]},
|
|
3184
|
+
{"val": 0}
|
|
3185
|
+
]
|
|
3186
|
+
},
|
|
3187
|
+
"@X_list": {
|
|
3188
|
+
"=": true,
|
|
3189
|
+
"list": [
|
|
3190
|
+
{"val": 1}, {"val": 2}, {"val": 3}
|
|
3191
|
+
]
|
|
3192
|
+
},
|
|
3193
|
+
"elements": { /* ... */ }
|
|
3194
|
+
},
|
|
3195
|
+
"F": { /* ... */ }
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
```
|
|
3199
|
+
</details>
|
|
3200
|
+
|
|
3201
|
+
Effective CSN with `stringifyAnnoXpr = true`:
|
|
3202
|
+
```jsonc
|
|
3203
|
+
{
|
|
3204
|
+
"definitions": {
|
|
3205
|
+
"E": {
|
|
3206
|
+
"kind": "entity",
|
|
3207
|
+
"@X_ref_simple": { "=": "a" },
|
|
3208
|
+
"@X_ref_nonsimple": "f[id > 1].id",
|
|
3209
|
+
"@X_xpr": "a + b",
|
|
3210
|
+
"@X_enum": { "#": "FOOL" },
|
|
3211
|
+
"@X_val": 33,
|
|
3212
|
+
"@X_func": "coalesce(a, 0)",
|
|
3213
|
+
"@X_list": "(1, 2, 3)",
|
|
3214
|
+
"elements": { /* ... */ }
|
|
3215
|
+
},
|
|
3216
|
+
"F": { /* ... */ }
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
```
|
|
3220
|
+
|
|
3221
|
+
|
|
3222
|
+
#### Note on CAP annotations
|
|
3223
|
+
|
|
3224
|
+
CAP has introduced some annotations as shortcuts for e.g. OData annotations. The full list can be found
|
|
3225
|
+
in [capire#common-annotations](https://cap.cloud.sap/docs/cds/annotations#common-annotations).
|
|
3226
|
+
|
|
3227
|
+
We keep the following annotations in Effective CSN:
|
|
3228
|
+
* `@title`
|
|
3229
|
+
* `@description`
|
|
3230
|
+
* `@readonly`
|
|
3231
|
+
* `@mandatory`
|
|
3232
|
+
* `@cds.valid.from/to`
|
|
3233
|
+
* `@cds.on....`
|
|
3234
|
+
|
|
3235
|
+
|
|
3236
|
+
### Localized metadata
|
|
3237
|
+
|
|
3238
|
+
Texts in metadata like `@Common.Label` usually are localized. The value of the
|
|
3239
|
+
annotation is a i18n key like
|
|
3240
|
+
```cds
|
|
3241
|
+
annotate schema.Airline with @title: '{i18n>Airline}';
|
|
3242
|
+
```
|
|
3243
|
+
and the actual texts are stored in i18n files.
|
|
3244
|
+
|
|
3245
|
+
It would be possible to store localized texts in the `i18n` section of CSN, but we don't
|
|
3246
|
+
use this for Effective CSN. Consumers have to read the texts directly from the i18n files.
|
|
3247
|
+
|
|
3248
|
+
|
|
3249
|
+
### Reduce to one service
|
|
3250
|
+
|
|
3251
|
+
If option `effectiveServiceName` is set, the output is filtered to contain only the
|
|
3252
|
+
named service definition and the artifacts contained in that service.
|
|
3253
|
+
All definitions outside the service are removed.
|
|
3254
|
+
|
|
3255
|
+
Example:
|
|
3256
|
+
CDS:
|
|
3257
|
+
```cds
|
|
3258
|
+
entity E {
|
|
3259
|
+
key id : Integer;
|
|
3260
|
+
f : Association to F;
|
|
3261
|
+
}
|
|
3262
|
+
entity F {
|
|
3263
|
+
key id : Integer;
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
service S {
|
|
3267
|
+
entity PE as projection on E;
|
|
3268
|
+
entity PF as projection on F;
|
|
3269
|
+
}
|
|
3270
|
+
```
|
|
3271
|
+
|
|
3272
|
+
<details>
|
|
3273
|
+
<summary>Effective CSN with option "effectiveServiceName"</summary>
|
|
3274
|
+
|
|
3275
|
+
Set `effectiveServiceName: S`:
|
|
3276
|
+
```json
|
|
3277
|
+
{
|
|
3278
|
+
"definitions": {
|
|
3279
|
+
"S": {
|
|
3280
|
+
"kind": "service"
|
|
3281
|
+
},
|
|
3282
|
+
"S.PE": {
|
|
3283
|
+
"kind": "entity",
|
|
3284
|
+
"query": { /* ... */ },
|
|
3285
|
+
"elements": {
|
|
3286
|
+
"id": {"key": true, "type": "cds.Integer"},
|
|
3287
|
+
"f": {
|
|
3288
|
+
"type": "cds.Association",
|
|
3289
|
+
"target": "S.PF",
|
|
3290
|
+
"on": [{"ref": ["f","id"]}, "=", {"ref": ["f_id"]}]
|
|
3291
|
+
},
|
|
3292
|
+
"f_id": {"type": "cds.Integer"}
|
|
3293
|
+
}
|
|
3294
|
+
},
|
|
3295
|
+
"S.PF": {
|
|
3296
|
+
"kind": "entity",
|
|
3297
|
+
"query": {
|
|
3298
|
+
"SELECT": {
|
|
3299
|
+
"from": {"ref": ["F"]},
|
|
3300
|
+
"columns": [{"ref": ["id"]}]
|
|
3301
|
+
}
|
|
3302
|
+
},
|
|
3303
|
+
"elements": {
|
|
3304
|
+
"id": {"key": true, "type": "cds.Integer"}
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
```
|
|
3310
|
+
</details>
|
|
3311
|
+
|
|
3312
|
+
Note:
|
|
3313
|
+
* If no service with the given name exists, a warning is emitted and the output contains no definitions.
|
|
3314
|
+
* Associations to a target outside of the service that cannot be redirected are reported as error.
|