@sap/cds-compiler 2.7.0 → 2.11.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 +167 -0
- package/bin/cdsc.js +42 -25
- package/bin/cdsse.js +1 -0
- package/doc/CHANGELOG_BETA.md +10 -0
- package/lib/api/.eslintrc.json +2 -0
- package/lib/api/main.js +17 -33
- package/lib/api/options.js +25 -13
- package/lib/api/validate.js +33 -9
- package/lib/backends.js +9 -8
- package/lib/base/dictionaries.js +2 -1
- package/lib/base/keywords.js +32 -2
- package/lib/base/message-registry.js +26 -2
- package/lib/base/messages.js +25 -9
- package/lib/base/model.js +5 -3
- package/lib/base/optionProcessorHelper.js +56 -22
- package/lib/checks/onConditions.js +5 -0
- package/lib/checks/selectItems.js +4 -0
- package/lib/checks/types.js +26 -2
- package/lib/checks/unknownMagic.js +41 -0
- package/lib/checks/validator.js +7 -2
- package/lib/compiler/assert-consistency.js +18 -5
- package/lib/compiler/base.js +65 -0
- package/lib/compiler/builtins.js +30 -1
- package/lib/compiler/checks.js +5 -2
- package/lib/compiler/definer.js +145 -120
- package/lib/compiler/index.js +16 -4
- package/lib/compiler/propagator.js +5 -2
- package/lib/compiler/resolver.js +207 -47
- package/lib/compiler/shared.js +47 -200
- package/lib/compiler/utils.js +173 -0
- package/lib/edm/annotations/genericTranslation.js +183 -187
- package/lib/edm/csn2edm.js +94 -98
- package/lib/edm/edm.js +16 -20
- package/lib/edm/edmPreprocessor.js +302 -115
- package/lib/edm/edmUtils.js +31 -12
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +28 -1
- package/lib/gen/language.tokens +79 -69
- package/lib/gen/languageLexer.interp +28 -1
- package/lib/gen/languageLexer.js +879 -805
- package/lib/gen/languageLexer.tokens +71 -62
- package/lib/gen/languageParser.js +5308 -4308
- package/lib/json/from-csn.js +59 -30
- package/lib/json/to-csn.js +354 -105
- package/lib/language/antlrParser.js +11 -0
- package/lib/language/errorStrategy.js +1 -0
- package/lib/language/genericAntlrParser.js +81 -14
- package/lib/language/language.g4 +163 -31
- package/lib/main.d.ts +136 -17
- package/lib/main.js +7 -1
- package/lib/model/api.js +78 -0
- package/lib/model/csnRefs.js +115 -32
- package/lib/model/csnUtils.js +71 -33
- package/lib/model/enrichCsn.js +36 -9
- package/lib/model/revealInternalProperties.js +20 -4
- package/lib/modelCompare/compare.js +2 -1
- package/lib/optionProcessor.js +33 -16
- package/lib/render/.eslintrc.json +3 -1
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/toCdl.js +60 -17
- package/lib/render/toHdbcds.js +122 -74
- package/lib/render/toSql.js +57 -32
- package/lib/render/utils/common.js +6 -10
- package/lib/sql-identifier.js +6 -1
- package/lib/transform/db/constraints.js +273 -119
- package/lib/transform/db/draft.js +9 -6
- package/lib/transform/db/expansion.js +19 -7
- package/lib/transform/db/flattening.js +31 -7
- package/lib/transform/db/transformExists.js +344 -66
- package/lib/transform/db/views.js +438 -0
- package/lib/transform/forHanaNew.js +65 -436
- package/lib/transform/forOdataNew.js +21 -10
- package/lib/transform/localized.js +2 -0
- package/lib/transform/odata/attachPath.js +19 -4
- package/lib/transform/odata/generateForeignKeyElements.js +11 -10
- package/lib/transform/odata/referenceFlattener.js +44 -38
- package/lib/transform/odata/sortByAssociationDependency.js +2 -2
- package/lib/transform/odata/structuralPath.js +72 -0
- package/lib/transform/odata/structureFlattener.js +13 -10
- package/lib/transform/odata/typesExposure.js +22 -12
- package/lib/transform/transformUtilsNew.js +55 -9
- package/lib/transform/translateAssocsToJoins.js +11 -17
- package/lib/transform/universalCsnEnricher.js +67 -0
- package/lib/utils/file.js +5 -3
- package/lib/utils/term.js +65 -42
- package/lib/utils/timetrace.js +48 -26
- package/package.json +1 -1
package/lib/render/toSql.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
const {
|
|
5
5
|
getLastPartOf, getLastPartOfRef,
|
|
6
6
|
hasValidSkipOrExists, isBuiltinType, generatedByCompilerVersion, getNormalizedQuery,
|
|
7
|
-
forEachDefinition, getResultingName,
|
|
7
|
+
forEachDefinition, getResultingName, getVariableReplacement,
|
|
8
8
|
} = require('../model/csnUtils');
|
|
9
9
|
const {
|
|
10
|
-
renderFunc,
|
|
10
|
+
renderFunc, beautifyExprArray, cdsToSqlTypes, getHanaComment, hasHanaComment,
|
|
11
11
|
} = require('./utils/common');
|
|
12
12
|
const {
|
|
13
13
|
renderReferentialConstraint, getIdentifierUtils,
|
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
const DuplicateChecker = require('./DuplicateChecker');
|
|
16
16
|
const { checkCSNVersion } = require('../json/csnVersion');
|
|
17
17
|
const { makeMessageFunction } = require('../base/messages');
|
|
18
|
-
const timetrace = require('../utils/timetrace');
|
|
18
|
+
const { timetrace } = require('../utils/timetrace');
|
|
19
19
|
const { isBetaEnabled, isDeprecatedEnabled } = require('../base/model');
|
|
20
20
|
const { smartFuncId } = require('../sql-identifier');
|
|
21
21
|
const { sortCsn } = require('../json/to-csn');
|
|
@@ -385,7 +385,7 @@ function toSqlDdl(csn, options) {
|
|
|
385
385
|
function reducesTypeSize(def) {
|
|
386
386
|
// HANA does not allow decreasing the value of any of those type parameters.
|
|
387
387
|
return def.old.type === def.new.type &&
|
|
388
|
-
|
|
388
|
+
[ 'length', 'precision', 'scale' ].some(param => def.new[param] < def.old[param]);
|
|
389
389
|
}
|
|
390
390
|
function getEltStr(defVariant, eltName) {
|
|
391
391
|
return defVariant.target
|
|
@@ -525,12 +525,12 @@ function toSqlDdl(csn, options) {
|
|
|
525
525
|
referentialConstraints[fileName] = renderReferentialConstraint(referentialConstraint, childEnv.indent, false, csn, options);
|
|
526
526
|
});
|
|
527
527
|
if (renderReferentialConstraintsAsHdbconstraint) {
|
|
528
|
-
Object.entries(referentialConstraints).forEach(
|
|
528
|
+
Object.entries(referentialConstraints).forEach(([ fileName, constraint ]) => {
|
|
529
529
|
resultObj.hdbconstraint[fileName] = constraint;
|
|
530
530
|
});
|
|
531
531
|
}
|
|
532
532
|
else {
|
|
533
|
-
Object.values(referentialConstraints).forEach(
|
|
533
|
+
Object.values(referentialConstraints).forEach((constraint) => {
|
|
534
534
|
result += `,\n${constraint}`;
|
|
535
535
|
});
|
|
536
536
|
}
|
|
@@ -546,8 +546,7 @@ function toSqlDdl(csn, options) {
|
|
|
546
546
|
= `UNIQUE INVERTED INDEX ${renderArtifactName(`${artifactName}_${cn}`)} ON ${tableName} (${c.map(cpath => quoteSqlId(cpath.ref[0])).join(', ')})`;
|
|
547
547
|
}
|
|
548
548
|
else {
|
|
549
|
-
result += `,\n${childEnv.indent}CONSTRAINT ${renderArtifactName(`${artifactName}_${cn}`)} UNIQUE (${
|
|
550
|
-
c.map(cpath => quoteSqlId(cpath.ref[0])).join(', ')})`;
|
|
549
|
+
result += `,\n${childEnv.indent}CONSTRAINT ${renderArtifactName(`${artifactName}_${cn}`)} UNIQUE (${c.map(cpath => quoteSqlId(cpath.ref[0])).join(', ')})`;
|
|
551
550
|
}
|
|
552
551
|
}
|
|
553
552
|
result += `${env.indent}\n)`;
|
|
@@ -568,7 +567,7 @@ function toSqlDdl(csn, options) {
|
|
|
568
567
|
if (options.toSql.dialect === 'hana')
|
|
569
568
|
renderIndexesInto(art.technicalConfig && art.technicalConfig.hana.indexes, artifactName, resultObj, env);
|
|
570
569
|
|
|
571
|
-
if (options.toSql.dialect === 'hana' && hasHanaComment(art, options
|
|
570
|
+
if (options.toSql.dialect === 'hana' && hasHanaComment(art, options))
|
|
572
571
|
result += ` COMMENT '${getHanaComment(art)}'`;
|
|
573
572
|
|
|
574
573
|
resultObj.hdbtable[artifactName] = result;
|
|
@@ -659,8 +658,7 @@ function toSqlDdl(csn, options) {
|
|
|
659
658
|
if (duplicateChecker)
|
|
660
659
|
duplicateChecker.addElement(quotedElementName, elm.$location, elementName);
|
|
661
660
|
|
|
662
|
-
let result = `${env.indent + quotedElementName} ${
|
|
663
|
-
renderTypeReference(artifactName, elementName, elm)
|
|
661
|
+
let result = `${env.indent + quotedElementName} ${renderTypeReference(artifactName, elementName, elm)
|
|
664
662
|
}${renderNullability(elm, true)}`;
|
|
665
663
|
if (elm.default)
|
|
666
664
|
result += ` DEFAULT ${renderExpr(elm.default, env)}`;
|
|
@@ -956,7 +954,7 @@ function toSqlDdl(csn, options) {
|
|
|
956
954
|
// An empty actual parameter list is rendered as `()`.
|
|
957
955
|
const ref = csn.definitions[path.ref[0].id] || csn.definitions[path.ref[0]];
|
|
958
956
|
if (ref && ref.params) {
|
|
959
|
-
result += `(${renderArgs(path.ref[0]
|
|
957
|
+
result += `(${renderArgs(path.ref[0] || {}, '=>', env, syntax)})`;
|
|
960
958
|
}
|
|
961
959
|
else if ([ 'udf' ].includes(syntax)) {
|
|
962
960
|
// if syntax is user defined function, render empty argument list
|
|
@@ -978,21 +976,23 @@ function toSqlDdl(csn, options) {
|
|
|
978
976
|
* Render function arguments or view parameters (positional if array, named if object/dict),
|
|
979
977
|
* using 'sep' as separator for positional parameters
|
|
980
978
|
*
|
|
981
|
-
* @param {
|
|
979
|
+
* @param {object} node with `args` to render
|
|
982
980
|
* @param {string} sep Separator between args
|
|
983
981
|
* @param {object} env Render environment
|
|
984
982
|
* @param {string} syntax Some magic A2J paramter - for calcview parameter rendering
|
|
985
983
|
* @returns {string} Rendered arguments
|
|
986
984
|
* @throws Throws if args is not an array or object.
|
|
987
985
|
*/
|
|
988
|
-
function renderArgs(
|
|
986
|
+
function renderArgs(node, sep, env, syntax) {
|
|
987
|
+
const args = node.args ? node.args : {};
|
|
989
988
|
// Positional arguments
|
|
990
989
|
if (Array.isArray(args))
|
|
991
990
|
return args.map(arg => renderExpr(arg, env)).join(', ');
|
|
992
991
|
|
|
993
992
|
// Named arguments (object/dict)
|
|
994
993
|
else if (typeof args === 'object')
|
|
995
|
-
|
|
994
|
+
// if this is a function param which is not a reference to the model, we must not quote it
|
|
995
|
+
return Object.keys(args).map(key => `${node.func ? key : decorateParameter(key, syntax)} ${sep} ${renderExpr(args[key], env)}`).join(', ');
|
|
996
996
|
|
|
997
997
|
|
|
998
998
|
throw new Error(`Unknown args: ${JSON.stringify(args)}`);
|
|
@@ -1054,7 +1054,7 @@ function toSqlDdl(csn, options) {
|
|
|
1054
1054
|
definitionsDuplicateChecker.addArtifact(art['@cds.persistence.name'], art && art.$location, artifactName);
|
|
1055
1055
|
let result = `VIEW ${viewName}`;
|
|
1056
1056
|
|
|
1057
|
-
if (options.toSql.dialect === 'hana' && hasHanaComment(art, options
|
|
1057
|
+
if (options.toSql.dialect === 'hana' && hasHanaComment(art, options))
|
|
1058
1058
|
result += ` COMMENT '${getHanaComment(art)}'`;
|
|
1059
1059
|
|
|
1060
1060
|
result += renderParameterDefinitions(artifactName, art.params);
|
|
@@ -1088,8 +1088,15 @@ function toSqlDdl(csn, options) {
|
|
|
1088
1088
|
const p = params[pn];
|
|
1089
1089
|
if (p.notNull === true || p.notNull === false)
|
|
1090
1090
|
info(null, [ 'definitions', artifactName, 'params', pn ], 'Not Null constraints on SQL view parameters are not allowed and are ignored');
|
|
1091
|
-
|
|
1092
|
-
|
|
1091
|
+
// do not quote parameter identifiers for naming mode "quoted" / "hdbcds"
|
|
1092
|
+
// this would be an incompatible change, as non-uppercased, quoted identifiers
|
|
1093
|
+
// are rejected by the HANA compiler.
|
|
1094
|
+
let pIdentifier;
|
|
1095
|
+
if (options.toSql.names === 'quoted' || options.toSql.names === 'hdbcds')
|
|
1096
|
+
pIdentifier = prepareIdentifier(pn);
|
|
1097
|
+
else
|
|
1098
|
+
pIdentifier = quoteSqlId(pn);
|
|
1099
|
+
let pstr = `IN ${pIdentifier} ${renderTypeReference(artifactName, pn, p)}`;
|
|
1093
1100
|
if (p.default)
|
|
1094
1101
|
pstr += ` DEFAULT ${renderExpr(p.default)}`;
|
|
1095
1102
|
|
|
@@ -1144,12 +1151,11 @@ function toSqlDdl(csn, options) {
|
|
|
1144
1151
|
const childEnv = increaseIndent(env);
|
|
1145
1152
|
result += `SELECT${select.distinct ? ' DISTINCT' : ''}`;
|
|
1146
1153
|
// FIXME: We probably also need to consider `excluding` here ?
|
|
1147
|
-
result += `\n${
|
|
1148
|
-
(select.
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
.join(',\n')}\n`;
|
|
1154
|
+
result += `\n${(select.columns || [ '*' ])
|
|
1155
|
+
.filter(col => !(select.mixin || Object.create(null))[firstPathStepId(col.ref)]) // No mixin columns
|
|
1156
|
+
.map(col => renderViewColumn(col, childEnv))
|
|
1157
|
+
.filter(s => s !== '')
|
|
1158
|
+
.join(',\n')}\n`;
|
|
1153
1159
|
result += `${env.indent}FROM ${renderViewSource(artifactName, select.from, env)}`;
|
|
1154
1160
|
if (select.where)
|
|
1155
1161
|
result += `\n${env.indent}WHERE ${renderExpr(select.where, env, true, true)}`;
|
|
@@ -1336,7 +1342,8 @@ function toSqlDdl(csn, options) {
|
|
|
1336
1342
|
function renderExpr(x, env, inline = true, nestedExpr = false) {
|
|
1337
1343
|
// Compound expression
|
|
1338
1344
|
if (Array.isArray(x)) {
|
|
1339
|
-
|
|
1345
|
+
const tokens = x.map(item => renderExpr(item, env, inline, nestedExpr));
|
|
1346
|
+
return beautifyExprArray(tokens);
|
|
1340
1347
|
}
|
|
1341
1348
|
else if (typeof x === 'object' && x !== null) {
|
|
1342
1349
|
if (nestedExpr && x.cast && x.cast.type)
|
|
@@ -1376,6 +1383,8 @@ function toSqlDdl(csn, options) {
|
|
|
1376
1383
|
// Function call, possibly with args (use '=>' for named args)
|
|
1377
1384
|
else if (x.func) {
|
|
1378
1385
|
const funcName = smartFuncId(prepareIdentifier(x.func), options.toSql.dialect);
|
|
1386
|
+
if (x.xpr)
|
|
1387
|
+
return renderWindowFunction(funcName, x, env);
|
|
1379
1388
|
return renderFunc(funcName, x, options.toSql.dialect, a => renderArgs(a, '=>', env, null));
|
|
1380
1389
|
}
|
|
1381
1390
|
// Nested expression
|
|
@@ -1398,29 +1407,36 @@ function toSqlDdl(csn, options) {
|
|
|
1398
1407
|
throw new Error(`Unknown expression: ${JSON.stringify(x)}`);
|
|
1399
1408
|
}
|
|
1400
1409
|
|
|
1410
|
+
function renderWindowFunction(funcName, node, env) {
|
|
1411
|
+
const suffix = node.xpr.shift(); // OVER
|
|
1412
|
+
let r = `${funcName}(${renderArgs(node, '=>', env, null)})`;
|
|
1413
|
+
r += ` ${suffix} (${renderExpr(node.xpr, env)})`;
|
|
1414
|
+
return r;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1401
1417
|
function renderExpressionLiteral(x) {
|
|
1402
1418
|
// Literal value, possibly with explicit 'literal' property
|
|
1403
1419
|
switch (x.literal || typeof x.val) {
|
|
1404
1420
|
case 'number':
|
|
1405
1421
|
case 'boolean':
|
|
1406
1422
|
case 'null':
|
|
1407
|
-
|
|
1423
|
+
// 17.42, NULL, TRUE
|
|
1408
1424
|
return String(x.val).toUpperCase();
|
|
1409
1425
|
case 'x':
|
|
1410
|
-
|
|
1426
|
+
// x'f000'
|
|
1411
1427
|
return `${x.literal}'${x.val}'`;
|
|
1412
1428
|
case 'date':
|
|
1413
1429
|
case 'time':
|
|
1414
1430
|
case 'timestamp':
|
|
1415
1431
|
if (options.toSql.dialect === 'sqlite') {
|
|
1416
|
-
|
|
1432
|
+
// simple string literal '2017-11-02'
|
|
1417
1433
|
return `'${x.val}'`;
|
|
1418
1434
|
}
|
|
1419
1435
|
// date'2017-11-02'
|
|
1420
1436
|
return `${x.literal}'${x.val}'`;
|
|
1421
1437
|
|
|
1422
1438
|
case 'string':
|
|
1423
|
-
|
|
1439
|
+
// 'foo', with proper escaping
|
|
1424
1440
|
return `'${x.val.replace(/'/g, '\'\'')}'`;
|
|
1425
1441
|
case 'object':
|
|
1426
1442
|
if (x.val === null)
|
|
@@ -1434,7 +1450,12 @@ function toSqlDdl(csn, options) {
|
|
|
1434
1450
|
|
|
1435
1451
|
function renderExpressionRef(x) {
|
|
1436
1452
|
if (!x.param && !x.global) {
|
|
1453
|
+
const magicReplacement = getVariableReplacement(x.ref, options);
|
|
1454
|
+
|
|
1437
1455
|
if (x.ref[0] === '$user') {
|
|
1456
|
+
if (magicReplacement !== null)
|
|
1457
|
+
return `'${magicReplacement}'`;
|
|
1458
|
+
|
|
1438
1459
|
const result = render$user(x);
|
|
1439
1460
|
// Invalid second path step doesn't cause a return
|
|
1440
1461
|
if (result)
|
|
@@ -1446,6 +1467,9 @@ function toSqlDdl(csn, options) {
|
|
|
1446
1467
|
if (result)
|
|
1447
1468
|
return result;
|
|
1448
1469
|
}
|
|
1470
|
+
else if (x.ref[0] === '$session' && magicReplacement !== null) {
|
|
1471
|
+
return `'${magicReplacement}'`;
|
|
1472
|
+
}
|
|
1449
1473
|
}
|
|
1450
1474
|
// FIXME: We currently cannot distinguish whether '$parameters' was quoted or not - we
|
|
1451
1475
|
// assume that it was not if the path has length 2 (
|
|
@@ -1468,6 +1492,7 @@ function toSqlDdl(csn, options) {
|
|
|
1468
1492
|
function render$user(x) {
|
|
1469
1493
|
// FIXME: this is all not enough: we might need an explicit select item alias
|
|
1470
1494
|
if (x.ref[1] === 'id') {
|
|
1495
|
+
// Keep the old-style for compatibilty with magicVars.id - instead of magicVars.user.id...
|
|
1471
1496
|
if (options.toSql.user && typeof options.toSql.user === 'string' || options.toSql.user instanceof String)
|
|
1472
1497
|
return `'${options.toSql.user}'`;
|
|
1473
1498
|
|
|
@@ -1487,7 +1512,7 @@ function toSqlDdl(csn, options) {
|
|
|
1487
1512
|
}
|
|
1488
1513
|
return 'SESSION_CONTEXT(\'LOCALE\')';
|
|
1489
1514
|
}
|
|
1490
|
-
// Basically: Second path step was invalid, do nothing
|
|
1515
|
+
// Basically: Second path step was invalid, do nothing - should not happen, see 'unknownMagic.js'
|
|
1491
1516
|
return null;
|
|
1492
1517
|
}
|
|
1493
1518
|
/**
|
|
@@ -1585,13 +1610,13 @@ function toSqlDdl(csn, options) {
|
|
|
1585
1610
|
|
|
1586
1611
|
// Not really a path step but an object-like function call
|
|
1587
1612
|
if (s.func)
|
|
1588
|
-
return `${s.func}(${renderArgs(s
|
|
1613
|
+
return `${s.func}(${renderArgs(s, '=>', env, null)})`;
|
|
1589
1614
|
|
|
1590
1615
|
// Path step, possibly with view parameters and/or filters
|
|
1591
1616
|
let result = `${quoteSqlId(s.id)}`;
|
|
1592
1617
|
if (s.args) {
|
|
1593
1618
|
// View parameters
|
|
1594
|
-
result += `(${renderArgs(s
|
|
1619
|
+
result += `(${renderArgs(s, '=>', env, null)})`;
|
|
1595
1620
|
}
|
|
1596
1621
|
if (s.where) {
|
|
1597
1622
|
// Filter, possibly with cardinality
|
|
@@ -33,7 +33,7 @@ const { implicitAs } = require('../../model/csnRefs');
|
|
|
33
33
|
function renderFunc( funcName, node, dialect, renderArgs) {
|
|
34
34
|
if (funcWithoutParen( node, dialect ))
|
|
35
35
|
return funcName;
|
|
36
|
-
return `${funcName}(${renderArgs( node
|
|
36
|
+
return `${funcName}(${renderArgs( node )})`;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -53,19 +53,14 @@ function funcWithoutParen( node, dialect ) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* Process
|
|
56
|
+
* Process already rendered expression parts by joining them nicely
|
|
57
57
|
*
|
|
58
|
-
* @param {Array}
|
|
59
|
-
* @param {Function} renderExpr Function to render expressions
|
|
60
|
-
* @param {CdlRenderEnvironment} env Environment for rendering
|
|
61
|
-
* @param {boolean} inline Wether to render the expression inline
|
|
62
|
-
* @param {boolean} inExpr Wether to render as if a subexpression
|
|
58
|
+
* @param {Array} tokens Array of expression tokens
|
|
63
59
|
*
|
|
64
60
|
* @returns {string} The rendered xpr
|
|
65
61
|
*/
|
|
66
|
-
function
|
|
62
|
+
function beautifyExprArray(tokens) {
|
|
67
63
|
// Simply concatenate array parts with spaces (with a tiny bit of beautification)
|
|
68
|
-
const tokens = xpr.map(item => renderExpr(item, env, inline, inExpr));
|
|
69
64
|
let result = '';
|
|
70
65
|
for (let i = 0; i < tokens.length; i++) {
|
|
71
66
|
result += tokens[i];
|
|
@@ -378,7 +373,7 @@ function getHanaComment(obj) {
|
|
|
378
373
|
|
|
379
374
|
module.exports = {
|
|
380
375
|
renderFunc,
|
|
381
|
-
|
|
376
|
+
beautifyExprArray,
|
|
382
377
|
getNamespace,
|
|
383
378
|
getRealName,
|
|
384
379
|
addIntermediateContexts,
|
|
@@ -387,4 +382,5 @@ module.exports = {
|
|
|
387
382
|
hasHanaComment,
|
|
388
383
|
getHanaComment,
|
|
389
384
|
findElement,
|
|
385
|
+
funcWithoutParen,
|
|
390
386
|
};
|
package/lib/sql-identifier.js
CHANGED
|
@@ -51,7 +51,12 @@ const sqlDialects = {
|
|
|
51
51
|
effectiveName: name => name.toUpperCase(),
|
|
52
52
|
asDelimitedId: name => `"${ name.replace(/"/g, '""')}"`,
|
|
53
53
|
},
|
|
54
|
-
|
|
54
|
+
hdbcds: {
|
|
55
|
+
regularRegex: /^[A-Za-z_][A-Za-z_0-9]*$/,
|
|
56
|
+
reservedWords: keywords.hdbcds,
|
|
57
|
+
effectiveName: name => name,
|
|
58
|
+
asDelimitedId: name => `"${ name.replace(/"/g, '""')}"`,
|
|
59
|
+
},
|
|
55
60
|
};
|
|
56
61
|
|
|
57
62
|
function smartId( name, dialect ) {
|