@sap/cds-compiler 3.4.4 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +1 -0
- package/bin/cds_update_identifiers.js +5 -5
- package/bin/cdsc.js +12 -12
- package/doc/CHANGELOG_ARCHIVE.md +1 -1
- package/doc/CHANGELOG_BETA.md +9 -1
- package/doc/CHANGELOG_DEPRECATED.md +2 -0
- package/lib/api/main.js +58 -59
- package/lib/api/options.js +4 -2
- package/lib/api/validate.js +2 -2
- package/lib/base/cleanSymbols.js +2 -3
- package/lib/base/dictionaries.js +6 -6
- package/lib/base/error.js +2 -2
- package/lib/base/keywords.js +6 -6
- package/lib/base/location.js +11 -12
- package/lib/base/message-registry.js +124 -28
- package/lib/base/messages.js +247 -179
- package/lib/base/model.js +14 -11
- package/lib/base/node-helpers.js +9 -10
- package/lib/base/optionProcessorHelper.js +138 -129
- package/lib/checks/actionsFunctions.js +5 -5
- package/lib/checks/annotationsOData.js +4 -4
- package/lib/checks/arrayOfs.js +1 -1
- package/lib/checks/cdsPersistence.js +1 -1
- package/lib/checks/checkForTypes.js +3 -3
- package/lib/checks/defaultValues.js +3 -3
- package/lib/checks/elements.js +7 -7
- package/lib/checks/emptyOrOnlyVirtual.js +2 -2
- package/lib/checks/foreignKeys.js +1 -1
- package/lib/checks/invalidTarget.js +4 -4
- package/lib/checks/managedInType.js +1 -1
- package/lib/checks/managedWithoutKeys.js +1 -1
- package/lib/checks/nonexpandableStructured.js +5 -3
- package/lib/checks/nullableKeys.js +1 -1
- package/lib/checks/onConditions.js +5 -6
- package/lib/checks/parameters.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -2
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +4 -4
- package/lib/checks/types.js +7 -7
- package/lib/checks/utils.js +4 -4
- package/lib/checks/validator.js +16 -13
- package/lib/compiler/.eslintrc.json +1 -1
- package/lib/compiler/assert-consistency.js +0 -1
- package/lib/compiler/builtins.js +1 -1
- package/lib/compiler/checks.js +73 -15
- package/lib/compiler/define.js +3 -7
- package/lib/compiler/extend.js +212 -32
- package/lib/compiler/finalize-parse-cdl.js +7 -2
- package/lib/compiler/index.js +17 -14
- package/lib/compiler/populate.js +2 -5
- package/lib/compiler/propagator.js +2 -0
- package/lib/compiler/shared.js +23 -12
- package/lib/compiler/tweak-assocs.js +5 -6
- package/lib/compiler/utils.js +6 -0
- package/lib/edm/annotations/genericTranslation.js +553 -319
- package/lib/edm/annotations/preprocessAnnotations.js +39 -35
- package/lib/edm/csn2edm.js +88 -75
- package/lib/edm/edm.js +17 -3
- package/lib/edm/edmAnnoPreprocessor.js +5 -5
- package/lib/edm/edmPreprocessor.js +106 -76
- package/lib/edm/edmUtils.js +41 -2
- package/lib/gen/Dictionary.json +34 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +66 -63
- package/lib/gen/language.tokens +81 -81
- package/lib/gen/languageLexer.interp +4 -10
- package/lib/gen/languageLexer.js +854 -869
- package/lib/gen/languageLexer.tokens +79 -81
- package/lib/gen/languageParser.js +14360 -14146
- package/lib/inspect/inspectModelStatistics.js +2 -2
- package/lib/inspect/inspectPropagation.js +6 -6
- package/lib/inspect/inspectUtils.js +2 -2
- package/lib/json/from-csn.js +82 -40
- package/lib/json/to-csn.js +82 -157
- package/lib/language/.eslintrc.json +1 -4
- package/lib/language/genericAntlrParser.js +59 -38
- package/lib/language/language.g4 +1508 -1490
- package/lib/language/multiLineStringParser.js +1 -1
- package/lib/main.js +3 -3
- package/lib/model/csnUtils.js +130 -122
- package/lib/model/revealInternalProperties.js +1 -1
- package/lib/model/sortViews.js +4 -6
- package/lib/modelCompare/utils/filter.js +4 -3
- package/lib/optionProcessor.js +5 -0
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/manageConstraints.js +12 -12
- package/lib/render/toCdl.js +225 -159
- package/lib/render/toHdbcds.js +63 -63
- package/lib/render/toRename.js +5 -5
- package/lib/render/toSql.js +55 -65
- package/lib/render/utils/common.js +20 -37
- package/lib/render/utils/delta.js +3 -3
- package/lib/render/utils/sql.js +22 -6
- package/lib/render/utils/stringEscapes.js +3 -3
- package/lib/transform/db/applyTransformations.js +3 -3
- package/lib/transform/db/assertUnique.js +13 -12
- package/lib/transform/db/associations.js +5 -5
- package/lib/transform/db/cdsPersistence.js +10 -8
- package/lib/transform/db/constraints.js +14 -14
- package/lib/transform/db/expansion.js +20 -22
- package/lib/transform/db/flattening.js +24 -42
- package/lib/transform/db/groupByOrderBy.js +3 -3
- package/lib/transform/db/temporal.js +6 -6
- package/lib/transform/db/transformExists.js +23 -23
- package/lib/transform/db/views.js +16 -16
- package/lib/transform/draft/db.js +10 -10
- package/lib/transform/draft/odata.js +2 -2
- package/lib/transform/forOdataNew.js +12 -40
- package/lib/transform/forRelationalDB.js +17 -7
- package/lib/transform/localized.js +2 -2
- package/lib/transform/odata/toFinalBaseType.js +41 -27
- package/lib/transform/odata/typesExposure.js +106 -62
- package/lib/transform/parseExpr.js +209 -106
- package/lib/transform/transformUtilsNew.js +2 -2
- package/lib/transform/translateAssocsToJoins.js +24 -19
- package/lib/transform/universalCsn/coreComputed.js +10 -10
- package/lib/transform/universalCsn/universalCsnEnricher.js +26 -26
- package/lib/transform/universalCsn/utils.js +3 -3
- package/lib/utils/file.js +5 -5
- package/lib/utils/moduleResolve.js +13 -13
- package/lib/utils/objectUtils.js +6 -6
- package/lib/utils/term.js +5 -2
- package/lib/utils/timetrace.js +51 -24
- package/package.json +5 -7
- package/share/messages/check-proper-type-of.md +1 -1
- package/share/messages/message-explanations.json +1 -1
- package/share/messages/redirected-to-complex.md +4 -4
- package/share/messages/{syntax-expecting-integer.md → syntax-expecting-unsigned-int.md} +7 -4
package/lib/render/toSql.js
CHANGED
|
@@ -77,12 +77,12 @@ const { ModelError } = require('../base/error');
|
|
|
77
77
|
* @param {CSN.Options} options Transformation options
|
|
78
78
|
* @returns {object} Dictionary of artifact-type:artifacts, where artifacts is a dictionary of name:content
|
|
79
79
|
*/
|
|
80
|
-
function toSqlDdl(csn, options) {
|
|
80
|
+
function toSqlDdl( csn, options ) {
|
|
81
81
|
timetrace.start('SQL rendering');
|
|
82
82
|
const {
|
|
83
83
|
error, warning, info, throwWithAnyError,
|
|
84
84
|
} = makeMessageFunction(csn, options, 'to.sql');
|
|
85
|
-
const { quoteSqlId, prepareIdentifier } = getIdentifierUtils(options);
|
|
85
|
+
const { quoteSqlId, prepareIdentifier, renderArtifactName } = getIdentifierUtils(csn, options);
|
|
86
86
|
|
|
87
87
|
const exprRenderer = createExpressionRenderer({
|
|
88
88
|
// FIXME: For the sake of simplicity, we should get away from all this uppercasing in toSql
|
|
@@ -119,7 +119,7 @@ function toSqlDdl(csn, options) {
|
|
|
119
119
|
},
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
function renderExpr(x, env) {
|
|
122
|
+
function renderExpr( x, env ) {
|
|
123
123
|
return exprRenderer.renderExpr(x, env);
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -252,8 +252,7 @@ function toSqlDdl(csn, options) {
|
|
|
252
252
|
for (const name in deletions)
|
|
253
253
|
deletions[name] = `${options.testMode ? '' : sqlVersionLine}${deletions[name]}`;
|
|
254
254
|
|
|
255
|
-
|
|
256
|
-
timetrace.stop();
|
|
255
|
+
timetrace.stop('SQL rendering');
|
|
257
256
|
return mainResultObj;
|
|
258
257
|
|
|
259
258
|
/**
|
|
@@ -264,7 +263,7 @@ function toSqlDdl(csn, options) {
|
|
|
264
263
|
* @param {object} resultObj Result collector
|
|
265
264
|
* @param {object} env Render environment
|
|
266
265
|
*/
|
|
267
|
-
function renderArtifactInto(artifactName, art, resultObj, env) {
|
|
266
|
+
function renderArtifactInto( artifactName, art, resultObj, env ) {
|
|
268
267
|
// Ignore whole artifacts if forRelationalDB says so
|
|
269
268
|
if (art.abstract || hasValidSkipOrExists(art))
|
|
270
269
|
return;
|
|
@@ -306,7 +305,7 @@ function toSqlDdl(csn, options) {
|
|
|
306
305
|
* @param {object} resultObj Result collector
|
|
307
306
|
* @param {object} env Render environment
|
|
308
307
|
*/
|
|
309
|
-
function renderArtifactExtensionInto(artifactName, artifact, ext, resultObj, env) {
|
|
308
|
+
function renderArtifactExtensionInto( artifactName, artifact, ext, resultObj, env ) {
|
|
310
309
|
// Property kind is always omitted for elements and can be omitted for
|
|
311
310
|
// top-level type definitions, it does not exist for extensions.
|
|
312
311
|
if (artifactName && !ext.query)
|
|
@@ -317,52 +316,36 @@ function toSqlDdl(csn, options) {
|
|
|
317
316
|
}
|
|
318
317
|
|
|
319
318
|
// Render an artifact deletion into the appropriate dictionary of 'resultObj'.
|
|
320
|
-
function renderArtifactDeletionInto(artifactName, art, resultObj) {
|
|
319
|
+
function renderArtifactDeletionInto( artifactName, art, resultObj ) {
|
|
321
320
|
const tableName = renderArtifactName(artifactName);
|
|
322
321
|
deletionsDuplicateChecker.addArtifact(tableName, art.$location, artifactName);
|
|
323
322
|
|
|
324
323
|
addDeletion(resultObj, artifactName, `DROP TABLE ${tableName}`);
|
|
325
324
|
}
|
|
326
325
|
|
|
327
|
-
/**
|
|
328
|
-
* Given the following artifact name: namespace.prefix.entity.with.dot, render the following,
|
|
329
|
-
* depending on the naming mode:
|
|
330
|
-
* - plain: NAMESPACE_PREFIX_ENTITY_WITH_DOT
|
|
331
|
-
* - quoted: namespace.prefix.entity_with_dot
|
|
332
|
-
* - hdbcds: namespace::prefix.entity_with_dot
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
* @param {string} artifactName Artifact name to render
|
|
336
|
-
*
|
|
337
|
-
* @returns {string} Artifact name
|
|
338
|
-
*/
|
|
339
|
-
function renderArtifactName(artifactName) {
|
|
340
|
-
return quoteSqlId(getResultingName(csn, options.sqlMapping, artifactName));
|
|
341
|
-
}
|
|
342
|
-
|
|
343
326
|
// Render an artifact migration into the appropriate dictionary of 'resultObj'.
|
|
344
327
|
// Only HANA SQL is currently supported.
|
|
345
|
-
function renderArtifactMigrationInto(artifactName, migration, resultObj, env) {
|
|
346
|
-
function reducesTypeSize(def) {
|
|
328
|
+
function renderArtifactMigrationInto( artifactName, migration, resultObj, env ) {
|
|
329
|
+
function reducesTypeSize( def ) {
|
|
347
330
|
// HANA does not allow decreasing the value of any of those type parameters.
|
|
348
331
|
return def.old.type === def.new.type &&
|
|
349
332
|
[ 'length', 'precision', 'scale' ].some(param => def.new[param] < def.old[param]);
|
|
350
333
|
}
|
|
351
|
-
function getEltStr(defVariant, eltName, changeType = 'extension') {
|
|
334
|
+
function getEltStr( defVariant, eltName, changeType = 'extension' ) {
|
|
352
335
|
return defVariant.target
|
|
353
336
|
? renderAssociationElement(eltName, defVariant, env)
|
|
354
337
|
: renderElement(artifactName, eltName, defVariant, null, null, activateAlterMode(env, changeType));
|
|
355
338
|
}
|
|
356
|
-
function getEltStrNoProps(defVariant, eltName, ...props) {
|
|
339
|
+
function getEltStrNoProps( defVariant, eltName, ...props ) {
|
|
357
340
|
const defNoProps = Object.assign({}, defVariant);
|
|
358
341
|
for (const prop of props)
|
|
359
342
|
delete defNoProps[prop];
|
|
360
343
|
return getEltStr(defNoProps, eltName);
|
|
361
344
|
}
|
|
362
|
-
function oldAnnoChangedIncompatibly(defOld, defNew) {
|
|
345
|
+
function oldAnnoChangedIncompatibly( defOld, defNew ) {
|
|
363
346
|
return typeof defOld === 'string' && defOld.trim().length && !(typeof defNew === 'string' && defNew.trim().startsWith(`${defOld.trim()} `));
|
|
364
347
|
}
|
|
365
|
-
function getUnknownSqlReason(anno, artName, defOld, defNew, eltName) {
|
|
348
|
+
function getUnknownSqlReason( anno, artName, defOld, defNew, eltName ) {
|
|
366
349
|
const changeKind = defNew === undefined
|
|
367
350
|
? `removed (previous value: ${JSON.stringify(defOld)})`
|
|
368
351
|
: `changed from ${JSON.stringify(defOld)} to ${JSON.stringify(defNew)}`;
|
|
@@ -482,7 +465,7 @@ function toSqlDdl(csn, options) {
|
|
|
482
465
|
* @param {object} resultObj Result collector
|
|
483
466
|
* @param {object} env Render environment
|
|
484
467
|
*/
|
|
485
|
-
function renderEntityInto(artifactName, art, resultObj, env) {
|
|
468
|
+
function renderEntityInto( artifactName, art, resultObj, env ) {
|
|
486
469
|
env._artifact = art;
|
|
487
470
|
const childEnv = increaseIndent(env);
|
|
488
471
|
const hanaTc = art.technicalConfig && art.technicalConfig.hana;
|
|
@@ -591,7 +574,7 @@ function toSqlDdl(csn, options) {
|
|
|
591
574
|
* @param {object} env Render environment
|
|
592
575
|
* @param {DuplicateChecker} duplicateChecker
|
|
593
576
|
*/
|
|
594
|
-
function renderExtendInto(artifactName, artifactElements, extElements, resultObj, env, duplicateChecker) {
|
|
577
|
+
function renderExtendInto( artifactName, artifactElements, extElements, resultObj, env, duplicateChecker ) {
|
|
595
578
|
const tableName = renderArtifactName(artifactName);
|
|
596
579
|
if (duplicateChecker)
|
|
597
580
|
duplicateChecker.addArtifact(tableName, undefined, artifactName);
|
|
@@ -607,7 +590,7 @@ function toSqlDdl(csn, options) {
|
|
|
607
590
|
}
|
|
608
591
|
}
|
|
609
592
|
|
|
610
|
-
function addMigration(resultObj, artifactName, drop, sqlArray, description) {
|
|
593
|
+
function addMigration( resultObj, artifactName, drop, sqlArray, description ) {
|
|
611
594
|
if (!(artifactName in resultObj.migrations))
|
|
612
595
|
resultObj.migrations[artifactName] = [];
|
|
613
596
|
|
|
@@ -620,7 +603,7 @@ function toSqlDdl(csn, options) {
|
|
|
620
603
|
resultObj.migrations[artifactName].push(...migrations);
|
|
621
604
|
}
|
|
622
605
|
|
|
623
|
-
function addDeletion(resultObj, artifactName, deletionSql) {
|
|
606
|
+
function addDeletion( resultObj, artifactName, deletionSql ) {
|
|
624
607
|
resultObj.deletions[artifactName] = deletionSql;
|
|
625
608
|
}
|
|
626
609
|
|
|
@@ -631,7 +614,7 @@ function toSqlDdl(csn, options) {
|
|
|
631
614
|
* @param {object} hanaTc Technical configuration object
|
|
632
615
|
* @returns {object} fzindex for the element
|
|
633
616
|
*/
|
|
634
|
-
function getFzIndex(elemName, hanaTc) {
|
|
617
|
+
function getFzIndex( elemName, hanaTc ) {
|
|
635
618
|
if (!hanaTc || !hanaTc.fzindexes || !hanaTc.fzindexes[elemName])
|
|
636
619
|
return undefined;
|
|
637
620
|
|
|
@@ -661,7 +644,7 @@ function toSqlDdl(csn, options) {
|
|
|
661
644
|
* @param {object} env Render environment
|
|
662
645
|
* @returns {string} Rendered element
|
|
663
646
|
*/
|
|
664
|
-
function renderElement(artifactName, elementName, elm, duplicateChecker, fzindex, env) {
|
|
647
|
+
function renderElement( artifactName, elementName, elm, duplicateChecker, fzindex, env ) {
|
|
665
648
|
if (elm.virtual || elm.target)
|
|
666
649
|
return '';
|
|
667
650
|
|
|
@@ -705,7 +688,7 @@ function toSqlDdl(csn, options) {
|
|
|
705
688
|
* @param {object} env Render environment
|
|
706
689
|
* @returns {string} Rendered association element
|
|
707
690
|
*/
|
|
708
|
-
function renderAssociationElement(elementName, elm, env) {
|
|
691
|
+
function renderAssociationElement( elementName, elm, env ) {
|
|
709
692
|
let result = '';
|
|
710
693
|
if (elm.target) {
|
|
711
694
|
result += env.indent;
|
|
@@ -741,7 +724,7 @@ function toSqlDdl(csn, options) {
|
|
|
741
724
|
* @param {object} env Render environment
|
|
742
725
|
* @returns {string} Rendered technical configuration
|
|
743
726
|
*/
|
|
744
|
-
function renderTechnicalConfiguration(tc, env) {
|
|
727
|
+
function renderTechnicalConfiguration( tc, env ) {
|
|
745
728
|
let result = '';
|
|
746
729
|
|
|
747
730
|
if (!tc)
|
|
@@ -785,7 +768,7 @@ function toSqlDdl(csn, options) {
|
|
|
785
768
|
* @param {object} resultObj Result collector
|
|
786
769
|
* @param {object} env Render environment
|
|
787
770
|
*/
|
|
788
|
-
function renderIndexesInto(indexes, artifactName, resultObj, env) {
|
|
771
|
+
function renderIndexesInto( indexes, artifactName, resultObj, env ) {
|
|
789
772
|
// Indices and full-text indices
|
|
790
773
|
for (const idxName in indexes || {}) {
|
|
791
774
|
let result = '';
|
|
@@ -817,7 +800,7 @@ function toSqlDdl(csn, options) {
|
|
|
817
800
|
* @param {Array} index Index definition
|
|
818
801
|
* @returns {Array} Index with artifact name inserted
|
|
819
802
|
*/
|
|
820
|
-
function insertTableName(index) {
|
|
803
|
+
function insertTableName( index ) {
|
|
821
804
|
const i = index.indexOf('index');
|
|
822
805
|
const j = index.indexOf('(');
|
|
823
806
|
if (i > index.length - 2 || !index[i + 1].ref || j < i || j > index.length - 2)
|
|
@@ -848,7 +831,7 @@ function toSqlDdl(csn, options) {
|
|
|
848
831
|
* @param {object} env Render environment
|
|
849
832
|
* @returns {string} Rendered view source
|
|
850
833
|
*/
|
|
851
|
-
function renderViewSource(artifactName, source, env) {
|
|
834
|
+
function renderViewSource( artifactName, source, env ) {
|
|
852
835
|
// Sub-SELECT
|
|
853
836
|
if (source.SELECT || source.SET) {
|
|
854
837
|
let result = `(${renderQuery(artifactName, source, increaseIndent(env))})`;
|
|
@@ -888,7 +871,7 @@ function toSqlDdl(csn, options) {
|
|
|
888
871
|
* @param {object} card CSN cardinality representation
|
|
889
872
|
* @returns {string} Rendered cardinality
|
|
890
873
|
*/
|
|
891
|
-
function renderJoinCardinality(card) {
|
|
874
|
+
function renderJoinCardinality( card ) {
|
|
892
875
|
let result = '';
|
|
893
876
|
if (card) {
|
|
894
877
|
if (card.srcmin && card.srcmin === 1)
|
|
@@ -916,7 +899,7 @@ function toSqlDdl(csn, options) {
|
|
|
916
899
|
* @param {object} env Render environment
|
|
917
900
|
* @returns {string} Rendered path
|
|
918
901
|
*/
|
|
919
|
-
function renderAbsolutePathWithAlias(artifactName, path, env) {
|
|
902
|
+
function renderAbsolutePathWithAlias( artifactName, path, env ) {
|
|
920
903
|
// This actually can't happen anymore because assoc2joins should have taken care of it
|
|
921
904
|
if (path.ref[0].where)
|
|
922
905
|
throw new ModelError(`"${artifactName}": Filters in FROM are not supported for conversion to SQL`);
|
|
@@ -954,7 +937,7 @@ function toSqlDdl(csn, options) {
|
|
|
954
937
|
* @param {object} env Render environment
|
|
955
938
|
* @returns {string} Rendered path
|
|
956
939
|
*/
|
|
957
|
-
function renderAbsolutePath(path, sep, env) {
|
|
940
|
+
function renderAbsolutePath( path, sep, env ) {
|
|
958
941
|
// Sanity checks
|
|
959
942
|
if (!path.ref)
|
|
960
943
|
throw new ModelError(`Expecting ref in path: ${JSON.stringify(path)}`);
|
|
@@ -1001,7 +984,7 @@ function toSqlDdl(csn, options) {
|
|
|
1001
984
|
* @returns {string} Rendered arguments
|
|
1002
985
|
* @throws Throws if args is not an array or object.
|
|
1003
986
|
*/
|
|
1004
|
-
function renderArgs(node, sep, env, syntax) {
|
|
987
|
+
function renderArgs( node, sep, env, syntax ) {
|
|
1005
988
|
const args = node.args ? node.args : {};
|
|
1006
989
|
// Positional arguments
|
|
1007
990
|
if (Array.isArray(args))
|
|
@@ -1023,7 +1006,7 @@ function toSqlDdl(csn, options) {
|
|
|
1023
1006
|
* @param {string|null} parameterSyntax Some magic A2J parameter - for calcview parameter rendering
|
|
1024
1007
|
* @returns {string} Rendered argument
|
|
1025
1008
|
*/
|
|
1026
|
-
function decorateParameter(arg, parameterSyntax) {
|
|
1009
|
+
function decorateParameter( arg, parameterSyntax ) {
|
|
1027
1010
|
if (parameterSyntax === 'calcview')
|
|
1028
1011
|
return `PLACEHOLDER."$$${arg}$$"`;
|
|
1029
1012
|
|
|
@@ -1040,7 +1023,7 @@ function toSqlDdl(csn, options) {
|
|
|
1040
1023
|
* @param {object} env Render environment
|
|
1041
1024
|
* @returns {string} Rendered column
|
|
1042
1025
|
*/
|
|
1043
|
-
function renderViewColumn(col, elements, env) {
|
|
1026
|
+
function renderViewColumn( col, elements, env ) {
|
|
1044
1027
|
let result = '';
|
|
1045
1028
|
const leaf = col.as || col.ref && col.ref[col.ref.length - 1] || col.func;
|
|
1046
1029
|
if (leaf && elements[leaf] && elements[leaf].virtual) {
|
|
@@ -1066,7 +1049,7 @@ function toSqlDdl(csn, options) {
|
|
|
1066
1049
|
* @param {object} env Render environment
|
|
1067
1050
|
* @returns {string} Rendered view
|
|
1068
1051
|
*/
|
|
1069
|
-
function renderView(artifactName, art, env) {
|
|
1052
|
+
function renderView( artifactName, art, env ) {
|
|
1070
1053
|
env._artifact = art;
|
|
1071
1054
|
const viewName = renderArtifactName(artifactName);
|
|
1072
1055
|
definitionsDuplicateChecker.addArtifact(art['@cds.persistence.name'], art && art.$location, artifactName);
|
|
@@ -1103,7 +1086,7 @@ function toSqlDdl(csn, options) {
|
|
|
1103
1086
|
* @param {Object} params Dictionary of parameters
|
|
1104
1087
|
* @returns {string} Rendered parameters
|
|
1105
1088
|
*/
|
|
1106
|
-
function renderParameterDefinitions(artifactName, params) {
|
|
1089
|
+
function renderParameterDefinitions( artifactName, params ) {
|
|
1107
1090
|
let result = '';
|
|
1108
1091
|
if (params) {
|
|
1109
1092
|
const parray = [];
|
|
@@ -1139,7 +1122,7 @@ function toSqlDdl(csn, options) {
|
|
|
1139
1122
|
* @param {CSN.Elements} [elements] to override direct query elements - e.g. leading union should win
|
|
1140
1123
|
* @returns {string} Rendered query
|
|
1141
1124
|
*/
|
|
1142
|
-
function renderQuery(artifactName, query, env, elements = null) {
|
|
1125
|
+
function renderQuery( artifactName, query, env, elements = null ) {
|
|
1143
1126
|
let result = '';
|
|
1144
1127
|
// Set operator, like UNION, INTERSECT, ...
|
|
1145
1128
|
if (query.SET) {
|
|
@@ -1205,7 +1188,7 @@ function toSqlDdl(csn, options) {
|
|
|
1205
1188
|
* @param {Array} ref Array of refs
|
|
1206
1189
|
* @returns {string|undefined} Id of first path step
|
|
1207
1190
|
*/
|
|
1208
|
-
function firstPathStepId(ref) {
|
|
1191
|
+
function firstPathStepId( ref ) {
|
|
1209
1192
|
return ref && ref[0] && (ref[0].id || ref[0]);
|
|
1210
1193
|
}
|
|
1211
1194
|
|
|
@@ -1216,7 +1199,7 @@ function toSqlDdl(csn, options) {
|
|
|
1216
1199
|
* @param {object} env Renderenvironment
|
|
1217
1200
|
* @returns {string} Rendered LIMIT clause
|
|
1218
1201
|
*/
|
|
1219
|
-
function renderLimit(limit, env) {
|
|
1202
|
+
function renderLimit( limit, env ) {
|
|
1220
1203
|
let result = '';
|
|
1221
1204
|
if (limit.rows !== undefined)
|
|
1222
1205
|
result += `LIMIT ${renderExpr(limit.rows, env)}`;
|
|
@@ -1235,7 +1218,7 @@ function toSqlDdl(csn, options) {
|
|
|
1235
1218
|
* @param {object} env Render environment
|
|
1236
1219
|
* @returns {string} Rendered ORDER BY entry
|
|
1237
1220
|
*/
|
|
1238
|
-
function renderOrderByEntry(entry, env) {
|
|
1221
|
+
function renderOrderByEntry( entry, env ) {
|
|
1239
1222
|
let result = renderExpr(entry, env);
|
|
1240
1223
|
if (entry.sort)
|
|
1241
1224
|
result += ` ${entry.sort.toUpperCase()}`;
|
|
@@ -1254,7 +1237,7 @@ function toSqlDdl(csn, options) {
|
|
|
1254
1237
|
* @param {CSN.Element} elm CSN element
|
|
1255
1238
|
* @returns {string} Rendered type reference
|
|
1256
1239
|
*/
|
|
1257
|
-
function renderTypeReference(artifactName, elementName, elm) {
|
|
1240
|
+
function renderTypeReference( artifactName, elementName, elm ) {
|
|
1258
1241
|
let result = '';
|
|
1259
1242
|
|
|
1260
1243
|
// Anonymous structured type: Not supported with SQL (but shouldn't happen anyway after forHana flattened them)
|
|
@@ -1296,7 +1279,7 @@ function toSqlDdl(csn, options) {
|
|
|
1296
1279
|
* @param {string} typeName Name of the type
|
|
1297
1280
|
* @returns {string} Rendered type
|
|
1298
1281
|
*/
|
|
1299
|
-
function renderBuiltinType(typeName) {
|
|
1282
|
+
function renderBuiltinType( typeName ) {
|
|
1300
1283
|
const forHanaRenamesToEarly = {
|
|
1301
1284
|
'cds.UTCDateTime': 'cds.DateTime',
|
|
1302
1285
|
'cds.UTCTimestamp': 'cds.Timestamp',
|
|
@@ -1316,7 +1299,7 @@ function toSqlDdl(csn, options) {
|
|
|
1316
1299
|
* @param {boolean} deltaMode Look for a $notNull and use that with precedence over notNull
|
|
1317
1300
|
* @returns {string} NULL/NOT NULL or ''
|
|
1318
1301
|
*/
|
|
1319
|
-
function renderNullability(obj, treatKeyAsNotNull = false, deltaMode = false) {
|
|
1302
|
+
function renderNullability( obj, treatKeyAsNotNull = false, deltaMode = false ) {
|
|
1320
1303
|
if (deltaMode && obj.$notNull !== undefined) { // can be set via compare.js if it goes from "not null" to implicit "null"
|
|
1321
1304
|
return obj.$notNull ? ' NOT NULL' : ' NULL';
|
|
1322
1305
|
}
|
|
@@ -1336,7 +1319,7 @@ function toSqlDdl(csn, options) {
|
|
|
1336
1319
|
* @param {CSN.Element} elm CSN element
|
|
1337
1320
|
* @returns {string} Rendered type parameters
|
|
1338
1321
|
*/
|
|
1339
|
-
function renderTypeParameters(elm) {
|
|
1322
|
+
function renderTypeParameters( elm ) {
|
|
1340
1323
|
const params = [];
|
|
1341
1324
|
// Length, precision and scale (even if incomplete)
|
|
1342
1325
|
if (elm.length !== undefined)
|
|
@@ -1358,7 +1341,7 @@ function toSqlDdl(csn, options) {
|
|
|
1358
1341
|
return params.length === 0 ? '' : `(${params.join(', ')})`;
|
|
1359
1342
|
}
|
|
1360
1343
|
|
|
1361
|
-
function renderExpressionLiteral(x) {
|
|
1344
|
+
function renderExpressionLiteral( x ) {
|
|
1362
1345
|
// Literal value, possibly with explicit 'literal' property
|
|
1363
1346
|
switch (x.literal || typeof x.val) {
|
|
1364
1347
|
case 'number':
|
|
@@ -1392,7 +1375,7 @@ function toSqlDdl(csn, options) {
|
|
|
1392
1375
|
}
|
|
1393
1376
|
}
|
|
1394
1377
|
|
|
1395
|
-
function renderExpressionRef(x, env) {
|
|
1378
|
+
function renderExpressionRef( x, env ) {
|
|
1396
1379
|
if (!x.param && !x.global) {
|
|
1397
1380
|
const magicReplacement = getVariableReplacement(x.ref, options);
|
|
1398
1381
|
|
|
@@ -1524,7 +1507,7 @@ function toSqlDdl(csn, options) {
|
|
|
1524
1507
|
* @param {number} idx index of the path step in the overall path
|
|
1525
1508
|
* @returns {string} Rendered path step
|
|
1526
1509
|
*/
|
|
1527
|
-
function renderPathStep(s, idx) {
|
|
1510
|
+
function renderPathStep( s, idx ) {
|
|
1528
1511
|
// Simple id or absolute name
|
|
1529
1512
|
if (typeof (s) === 'string') {
|
|
1530
1513
|
// TODO: When is this actually executed and not handled already in renderExpr?
|
|
@@ -1573,7 +1556,7 @@ function toSqlDdl(csn, options) {
|
|
|
1573
1556
|
}
|
|
1574
1557
|
}
|
|
1575
1558
|
|
|
1576
|
-
function renderWindowFunction(funcName, node, fctEnv) {
|
|
1559
|
+
function renderWindowFunction( funcName, node, fctEnv ) {
|
|
1577
1560
|
let r = `${funcName}(${renderArgs(node, '=>', fctEnv, null)}) `;
|
|
1578
1561
|
r += renderExpr(node.xpr, fctEnv); // xpr[0] is 'over'
|
|
1579
1562
|
return r;
|
|
@@ -1585,7 +1568,7 @@ function toSqlDdl(csn, options) {
|
|
|
1585
1568
|
* @param {object} env Render environment
|
|
1586
1569
|
* @returns {object} Render environment with increased indent
|
|
1587
1570
|
*/
|
|
1588
|
-
function increaseIndent(env) {
|
|
1571
|
+
function increaseIndent( env ) {
|
|
1589
1572
|
return Object.assign({}, env, { indent: `${env.indent} ` });
|
|
1590
1573
|
}
|
|
1591
1574
|
/**
|
|
@@ -1595,7 +1578,7 @@ function toSqlDdl(csn, options) {
|
|
|
1595
1578
|
* @param {string} changeType 'extension' or 'migration'
|
|
1596
1579
|
* @returns {object} Render environment with alterMode
|
|
1597
1580
|
*/
|
|
1598
|
-
function activateAlterMode(env, changeType) {
|
|
1581
|
+
function activateAlterMode( env, changeType ) {
|
|
1599
1582
|
return Object.assign({ alterMode: true, changeType }, env);
|
|
1600
1583
|
}
|
|
1601
1584
|
}
|
|
@@ -1607,8 +1590,8 @@ function toSqlDdl(csn, options) {
|
|
|
1607
1590
|
* @param {string} sqlDialect
|
|
1608
1591
|
* @return {string}
|
|
1609
1592
|
*/
|
|
1610
|
-
function renderStringForSql(str, sqlDialect) {
|
|
1611
|
-
if (sqlDialect === 'hana' || sqlDialect === 'sqlite') {
|
|
1593
|
+
function renderStringForSql( str, sqlDialect ) {
|
|
1594
|
+
if (sqlDialect === 'hana' || sqlDialect === 'sqlite' || sqlDialect === 'h2') {
|
|
1612
1595
|
// SQLite
|
|
1613
1596
|
// ======
|
|
1614
1597
|
// SQLite's tokenizer available at
|
|
@@ -1618,6 +1601,13 @@ function renderStringForSql(str, sqlDialect) {
|
|
|
1618
1601
|
// <https://sqlite.org/nulinstr.html>.
|
|
1619
1602
|
//
|
|
1620
1603
|
//
|
|
1604
|
+
// H2
|
|
1605
|
+
// ======
|
|
1606
|
+
// H2's tokenizer available at
|
|
1607
|
+
// <https://github.com/h2database/h2database/blob/master/h2/src/main/org/h2/command/Tokenizer.java>.
|
|
1608
|
+
// For strings, see method "readCharacterString()".
|
|
1609
|
+
//
|
|
1610
|
+
//
|
|
1621
1611
|
// HANA
|
|
1622
1612
|
// ====
|
|
1623
1613
|
// Respects the specification available at
|
|
@@ -31,7 +31,7 @@ const { implicitAs } = require('../../model/csnRefs');
|
|
|
31
31
|
* @param {(a: string) => string} renderArgs Function to render function arguments
|
|
32
32
|
* @returns {string} Function string
|
|
33
33
|
*/
|
|
34
|
-
function renderFunc( funcName, node, dialect, renderArgs) {
|
|
34
|
+
function renderFunc( funcName, node, dialect, renderArgs ) {
|
|
35
35
|
if (funcWithoutParen( node, dialect ))
|
|
36
36
|
return funcName;
|
|
37
37
|
return `${funcName}(${renderArgs( node )})`;
|
|
@@ -60,7 +60,7 @@ function funcWithoutParen( node, dialect ) {
|
|
|
60
60
|
*
|
|
61
61
|
* @returns {string} The rendered xpr
|
|
62
62
|
*/
|
|
63
|
-
function beautifyExprArray(tokens) {
|
|
63
|
+
function beautifyExprArray( tokens ) {
|
|
64
64
|
// Simply concatenate array parts with spaces (with a tiny bit of beautification)
|
|
65
65
|
let result = '';
|
|
66
66
|
for (let i = 0; i < tokens.length; i++) {
|
|
@@ -79,7 +79,7 @@ function beautifyExprArray(tokens) {
|
|
|
79
79
|
* @param {string} artifactName Artifact name to use
|
|
80
80
|
* @returns {string} non-prefix part of the artifact name
|
|
81
81
|
*/
|
|
82
|
-
function getRealName(csn, artifactName) {
|
|
82
|
+
function getRealName( csn, artifactName ) {
|
|
83
83
|
const parts = artifactName.split('.');
|
|
84
84
|
// Length of 1 -> There can be no prefix
|
|
85
85
|
if (parts.length === 1)
|
|
@@ -118,7 +118,7 @@ function getRealName(csn, artifactName) {
|
|
|
118
118
|
* @param {string} artifactName Name of the artifact to check for
|
|
119
119
|
* @returns {string | null} Name of the topmost context or null
|
|
120
120
|
*/
|
|
121
|
-
function getParentContextName(csn, artifactName) {
|
|
121
|
+
function getParentContextName( csn, artifactName ) {
|
|
122
122
|
const parts = artifactName.split('.');
|
|
123
123
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
124
124
|
const name = parts.slice(0, i).join('.');
|
|
@@ -137,7 +137,7 @@ function getParentContextName(csn, artifactName) {
|
|
|
137
137
|
*
|
|
138
138
|
* @param {Function[]} killList Array to add cleanup functions to
|
|
139
139
|
*/
|
|
140
|
-
function addContextMarkers(csn, killList) {
|
|
140
|
+
function addContextMarkers( csn, killList ) {
|
|
141
141
|
const contextsToCreate = Object.create(null);
|
|
142
142
|
forEachDefinition(csn, (art, artifactName) => {
|
|
143
143
|
const namespace = getNamespace(csn, artifactName);
|
|
@@ -172,7 +172,7 @@ function addContextMarkers(csn, killList) {
|
|
|
172
172
|
* @param {string} artifactName Name of the current context
|
|
173
173
|
* @returns {string[]} All possible context names inbetween
|
|
174
174
|
*/
|
|
175
|
-
function getIntermediateContextNames(csn, parentName, artifactName) {
|
|
175
|
+
function getIntermediateContextNames( csn, parentName, artifactName ) {
|
|
176
176
|
const parentLength = parentName.split('.').length;
|
|
177
177
|
const parts = artifactName.split('.');
|
|
178
178
|
const names = [];
|
|
@@ -194,7 +194,7 @@ function getIntermediateContextNames(csn, parentName, artifactName) {
|
|
|
194
194
|
* @param {string} artifactName
|
|
195
195
|
* @param {Function[]} killList Array to add cleanup functions to
|
|
196
196
|
*/
|
|
197
|
-
function addMissingChildContexts(csn, artifactName, killList) {
|
|
197
|
+
function addMissingChildContexts( csn, artifactName, killList ) {
|
|
198
198
|
// Get all other definitions sharing the same prefix, sorted by shortest first
|
|
199
199
|
const possibleNames = Object.keys(csn.definitions).filter(name => name.startsWith(`${artifactName}.`)).sort((a, b) => a.length - b.length);
|
|
200
200
|
for (const name of possibleNames) {
|
|
@@ -203,7 +203,7 @@ function addMissingChildContexts(csn, artifactName, killList) {
|
|
|
203
203
|
addPossibleGaps(name.slice(artifactName.length + 1).split('.'), artifactName);
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
function addPossibleGaps(possibleGaps, gapArtifactName) {
|
|
206
|
+
function addPossibleGaps( possibleGaps, gapArtifactName ) {
|
|
207
207
|
for (const gap of possibleGaps) {
|
|
208
208
|
gapArtifactName += `.${gap}`;
|
|
209
209
|
if (!csn.definitions[gapArtifactName]) {
|
|
@@ -314,7 +314,7 @@ const cdsToHdbcdsTypes = {
|
|
|
314
314
|
* @param {CSN.Column} column Column from the same query
|
|
315
315
|
* @returns {CSN.Element}
|
|
316
316
|
*/
|
|
317
|
-
function findElement(elements, column) {
|
|
317
|
+
function findElement( elements, column ) {
|
|
318
318
|
if (!elements)
|
|
319
319
|
return undefined;
|
|
320
320
|
if (column.as)
|
|
@@ -333,7 +333,7 @@ function findElement(elements, column) {
|
|
|
333
333
|
*
|
|
334
334
|
* @param {Function[]} killList Array to add cleanup functions to
|
|
335
335
|
*/
|
|
336
|
-
function addIntermediateContexts(csn, killList) {
|
|
336
|
+
function addIntermediateContexts( csn, killList ) {
|
|
337
337
|
for (const artifactName in csn.definitions) {
|
|
338
338
|
const artifact = csn.definitions[artifactName];
|
|
339
339
|
if ((artifact.kind === 'context') && !artifact._ignore) {
|
|
@@ -365,7 +365,7 @@ function addIntermediateContexts(csn, killList) {
|
|
|
365
365
|
* @param {CSN.Options} options To check for `disableHanaComments`
|
|
366
366
|
* @returns {boolean}
|
|
367
367
|
*/
|
|
368
|
-
function hasHanaComment(obj, options) {
|
|
368
|
+
function hasHanaComment( obj, options ) {
|
|
369
369
|
return !options.disableHanaComments && typeof obj.doc === 'string';
|
|
370
370
|
}
|
|
371
371
|
/**
|
|
@@ -377,7 +377,7 @@ function hasHanaComment(obj, options) {
|
|
|
377
377
|
* @param {CSN.Artifact|CSN.Element} obj
|
|
378
378
|
* @returns {string}
|
|
379
379
|
*/
|
|
380
|
-
function getHanaComment(obj) {
|
|
380
|
+
function getHanaComment( obj ) {
|
|
381
381
|
return obj.doc.split('\n\n')[0].trim();
|
|
382
382
|
}
|
|
383
383
|
|
|
@@ -389,7 +389,7 @@ function getHanaComment(obj) {
|
|
|
389
389
|
* @param {object} obj
|
|
390
390
|
* @returns {object} object with .front and .back
|
|
391
391
|
*/
|
|
392
|
-
function getSqlSnippets(options, obj) {
|
|
392
|
+
function getSqlSnippets( options, obj ) {
|
|
393
393
|
const front = obj['@sql.prepend'] ? `${obj['@sql.prepend']} ` : '';
|
|
394
394
|
const back = obj['@sql.append'] ? ` ${obj['@sql.append']}` : '';
|
|
395
395
|
|
|
@@ -425,7 +425,7 @@ function getSqlSnippets(options, obj) {
|
|
|
425
425
|
* @property {Function} [renderExpr]
|
|
426
426
|
* @property {Function} [renderSubExpr]
|
|
427
427
|
* @property {boolean} [isNestedXpr]
|
|
428
|
-
* @property {
|
|
428
|
+
* @property {object} [env]
|
|
429
429
|
*/
|
|
430
430
|
|
|
431
431
|
/**
|
|
@@ -445,7 +445,7 @@ function getSqlSnippets(options, obj) {
|
|
|
445
445
|
* @property {Function} renderExpr
|
|
446
446
|
* @property {Function} renderSubExpr
|
|
447
447
|
* @property {boolean} isNestedXpr
|
|
448
|
-
* @property {
|
|
448
|
+
* @property {object} env
|
|
449
449
|
*/
|
|
450
450
|
|
|
451
451
|
/**
|
|
@@ -454,7 +454,7 @@ function getSqlSnippets(options, obj) {
|
|
|
454
454
|
*
|
|
455
455
|
* @param xpr
|
|
456
456
|
*/
|
|
457
|
-
function withoutCast(xpr) {
|
|
457
|
+
function withoutCast( xpr ) {
|
|
458
458
|
return !xpr.cast ? xpr : { ...xpr, cast: undefined };
|
|
459
459
|
}
|
|
460
460
|
|
|
@@ -465,12 +465,12 @@ function withoutCast(xpr) {
|
|
|
465
465
|
* @param {ExpressionConfiguration} rendererBase
|
|
466
466
|
* @returns {ExpressionRenderer} Expression rendering utility
|
|
467
467
|
*/
|
|
468
|
-
function createExpressionRenderer(rendererBase) {
|
|
468
|
+
function createExpressionRenderer( rendererBase ) {
|
|
469
469
|
const renderer = Object.create(rendererBase);
|
|
470
470
|
renderer.visitExpr = visitExpr;
|
|
471
471
|
/**
|
|
472
472
|
* @param {any} x
|
|
473
|
-
* @param {
|
|
473
|
+
* @param {object} env
|
|
474
474
|
*/
|
|
475
475
|
renderer.renderExpr = function renderExpr(x, env) {
|
|
476
476
|
/** @type {ExpressionRenderer} */
|
|
@@ -484,7 +484,7 @@ function createExpressionRenderer(rendererBase) {
|
|
|
484
484
|
};
|
|
485
485
|
/**
|
|
486
486
|
* @param {any} x
|
|
487
|
-
* @param {
|
|
487
|
+
* @param {object} env
|
|
488
488
|
*/
|
|
489
489
|
renderer.renderSubExpr = function renderSubExpr(x, env) {
|
|
490
490
|
/** @type {ExpressionRenderer} */
|
|
@@ -510,7 +510,7 @@ function createExpressionRenderer(rendererBase) {
|
|
|
510
510
|
* @this ExpressionRenderer
|
|
511
511
|
* @returns {string} Rendered expression
|
|
512
512
|
*/
|
|
513
|
-
function visitExpr(x) {
|
|
513
|
+
function visitExpr( x ) {
|
|
514
514
|
if (Array.isArray(x)) {
|
|
515
515
|
// Compound expression, e.g. for on- or where-conditions.
|
|
516
516
|
// If xpr is part of an array, it's always a nested xpr,
|
|
@@ -562,23 +562,6 @@ function visitExpr(x) {
|
|
|
562
562
|
throw new ModelError(`renderExpr(): Unknown expression: ${JSON.stringify(x)}`);
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
* @typedef CdlRenderEnvironment Rendering environment used throughout the render process.
|
|
568
|
-
*
|
|
569
|
-
* @property {string} indent Current indentation as a string, e.g. ' ' for two spaces.
|
|
570
|
-
* @property {CSN.Path} [path] CSN path to the current artifact
|
|
571
|
-
* @property {string} [currentArtifactName] Name of the current artifact
|
|
572
|
-
* @property {{[name: string]: {
|
|
573
|
-
quotedName: string,
|
|
574
|
-
quotedAlias: string
|
|
575
|
-
}}} topLevelAliases Dictionary of aliases for used artifact names
|
|
576
|
-
*
|
|
577
|
-
* @property {string} namePrefix Current name prefix (including trailing dot if not empty)
|
|
578
|
-
* @property {boolean} [skipKeys] Skip rendering keys in subqueries
|
|
579
|
-
* @property {CSN.Artifact} [_artifact] The original view artifact, used when rendering queries
|
|
580
|
-
*/
|
|
581
|
-
|
|
582
565
|
module.exports = {
|
|
583
566
|
renderFunc,
|
|
584
567
|
createExpressionRenderer,
|
|
@@ -36,7 +36,7 @@ class DeltaRenderer {
|
|
|
36
36
|
/**
|
|
37
37
|
* By default, we don't support rendering association-alters - only for HANA
|
|
38
38
|
*/
|
|
39
|
-
addAssociations() {
|
|
39
|
+
addAssociations(_artifactName, _extElements, _env) {
|
|
40
40
|
return [];
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -57,7 +57,7 @@ class DeltaRenderer {
|
|
|
57
57
|
/**
|
|
58
58
|
* No associations by default - only for HANA.
|
|
59
59
|
*/
|
|
60
|
-
dropAssociation() {
|
|
60
|
+
dropAssociation(_artifactName, _sqlId) {
|
|
61
61
|
return [];
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -208,7 +208,7 @@ class DeltaRendererH2 extends DeltaRenderer {
|
|
|
208
208
|
* @param {object} scopedFunctions
|
|
209
209
|
* @returns {DeltaRenderer}
|
|
210
210
|
*/
|
|
211
|
-
function getDeltaRenderer(options, scopedFunctions) {
|
|
211
|
+
function getDeltaRenderer( options, scopedFunctions ) {
|
|
212
212
|
switch (options.sqlDialect) {
|
|
213
213
|
case 'hana':
|
|
214
214
|
return new DeltaRendererHana(options, scopedFunctions);
|