@sap/cds-compiler 5.9.4 → 6.0.12
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 +117 -319
- package/README.md +1 -1
- package/bin/cds_update_identifiers.js +3 -5
- package/bin/cdsc.js +24 -9
- package/bin/cdshi.js +1 -1
- package/bin/cdsse.js +4 -4
- package/doc/CHANGELOG_BETA.md +11 -0
- package/doc/CHANGELOG_DEPRECATED.md +29 -0
- package/lib/api/main.js +8 -5
- package/lib/api/options.js +12 -10
- package/lib/base/builtins.js +1 -0
- package/lib/base/message-registry.js +191 -99
- package/lib/base/messages.js +35 -21
- package/lib/base/model.js +14 -24
- package/lib/checks/actionsFunctions.js +10 -20
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/elements.js +35 -10
- package/lib/checks/enums.js +31 -0
- package/lib/checks/foreignKeys.js +2 -2
- package/lib/checks/hasPersistedElements.js +5 -0
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedWithoutKeys.js +5 -4
- package/lib/checks/queryNoDbArtifacts.js +10 -8
- package/lib/checks/types.js +5 -5
- package/lib/checks/validator.js +6 -4
- package/lib/compiler/assert-consistency.js +13 -9
- package/lib/compiler/checks.js +20 -52
- package/lib/compiler/define.js +31 -6
- package/lib/compiler/extend.js +5 -1
- package/lib/compiler/generate.js +14 -17
- package/lib/compiler/populate.js +8 -31
- package/lib/compiler/propagator.js +21 -35
- package/lib/compiler/resolve.js +64 -29
- package/lib/compiler/shared.js +16 -4
- package/lib/compiler/tweak-assocs.js +1 -1
- package/lib/compiler/utils.js +1 -1
- package/lib/edm/annotations/edmJson.js +23 -20
- package/lib/edm/annotations/genericTranslation.js +12 -10
- package/lib/edm/csn2edm.js +50 -56
- package/lib/edm/edm.js +33 -28
- package/lib/edm/edmInboundChecks.js +2 -2
- package/lib/edm/edmPreprocessor.js +54 -88
- package/lib/edm/edmUtils.js +9 -12
- package/lib/gen/BaseParser.js +63 -52
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +1153 -1165
- package/lib/gen/Dictionary.json +21 -1
- package/lib/json/from-csn.js +70 -43
- package/lib/json/to-csn.js +6 -8
- package/lib/language/multiLineStringParser.js +3 -2
- package/lib/main.d.ts +58 -24
- package/lib/model/cloneCsn.js +3 -0
- package/lib/model/csnUtils.js +28 -39
- package/lib/model/xprAsTree.js +23 -9
- package/lib/modelCompare/compare.js +5 -4
- package/lib/optionProcessor.js +24 -17
- package/lib/parsers/AstBuildingParser.js +81 -25
- package/lib/parsers/XprTree.js +57 -3
- package/lib/parsers/identifiers.js +1 -1
- package/lib/parsers/index.js +0 -3
- package/lib/render/manageConstraints.js +25 -25
- package/lib/render/toCdl.js +173 -170
- package/lib/render/toHdbcds.js +126 -128
- package/lib/render/toRename.js +7 -7
- package/lib/render/toSql.js +128 -125
- package/lib/render/utils/common.js +47 -22
- package/lib/render/utils/delta.js +25 -25
- package/lib/render/utils/operators.js +2 -2
- package/lib/render/utils/pretty.js +5 -5
- package/lib/render/utils/sql.js +13 -13
- package/lib/render/utils/standardDatabaseFunctions.js +115 -103
- package/lib/render/utils/unique.js +4 -4
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +2 -2
- package/lib/transform/db/associations.js +6 -7
- package/lib/transform/db/assocsToQueries/utils.js +4 -5
- package/lib/transform/db/backlinks.js +12 -9
- package/lib/transform/db/cdsPersistence.js +8 -7
- package/lib/transform/db/constraints.js +13 -10
- package/lib/transform/db/expansion.js +7 -3
- package/lib/transform/db/flattening.js +4 -14
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/temporal.js +5 -7
- package/lib/transform/db/views.js +2 -4
- package/lib/transform/draft/db.js +8 -8
- package/lib/transform/draft/odata.js +10 -7
- package/lib/transform/forOdata.js +10 -5
- package/lib/transform/forRelationalDB.js +5 -75
- package/lib/transform/localized.js +1 -1
- package/lib/transform/odata/createForeignKeys.js +11 -10
- package/lib/transform/odata/flattening.js +8 -4
- package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +96 -0
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/transformUtils.js +4 -8
- package/lib/transform/translateAssocsToJoins.js +14 -7
- package/lib/transform/universalCsn/universalCsnEnricher.js +10 -4
- package/lib/utils/objectUtils.js +0 -17
- package/package.json +10 -13
- package/share/messages/def-upcoming-virtual-change.md +1 -1
- package/LICENSE +0 -37
- package/bin/cds_remove_invalid_whitespace.js +0 -138
- package/doc/CHANGELOG_ARCHIVE.md +0 -3604
- package/lib/gen/genericAntlrParser.js +0 -3
- package/lib/gen/language.checksum +0 -1
- package/lib/gen/language.interp +0 -456
- package/lib/gen/language.tokens +0 -180
- package/lib/gen/languageLexer.interp +0 -439
- package/lib/gen/languageLexer.js +0 -1483
- package/lib/gen/languageLexer.tokens +0 -167
- package/lib/gen/languageParser.js +0 -24941
- package/lib/language/antlrParser.js +0 -205
- package/lib/language/errorStrategy.js +0 -646
- package/lib/language/genericAntlrParser.js +0 -1572
- package/lib/parsers/CdlGrammar.g4 +0 -2070
|
@@ -14,71 +14,74 @@ const oDataFunctions = {
|
|
|
14
14
|
checkArgs.call(this, 'contains', args, 2);
|
|
15
15
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
16
16
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
17
|
-
return `(ifnull(instr(${x}, ${y}),0) <> 0)`;
|
|
17
|
+
return `(ifnull(instr(${ x }, ${ y }),0) <> 0)`;
|
|
18
18
|
},
|
|
19
19
|
startswith(signature) {
|
|
20
20
|
const { args } = signature;
|
|
21
21
|
checkArgs.call(this, 'startswith', args, 2);
|
|
22
22
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
23
23
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
24
|
-
return `coalesce((instr(${x}, ${y}) = 1), false)`;
|
|
24
|
+
return `coalesce((instr(${ x }, ${ y }) = 1), false)`;
|
|
25
25
|
}, // instr is 1 indexed
|
|
26
26
|
endswith(signature) {
|
|
27
27
|
const { args } = signature;
|
|
28
28
|
checkArgs.call(this, 'endswith', args, 2);
|
|
29
29
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
30
30
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
31
|
-
return `coalesce((substr(${x}, length(${x}) + 1 - length(${y})) = ${y}), false)`;
|
|
31
|
+
return `coalesce((substr(${ x }, length(${ x }) + 1 - length(${ y })) = ${ y }), false)`;
|
|
32
32
|
},
|
|
33
33
|
indexof(signature) {
|
|
34
34
|
const { args } = signature;
|
|
35
35
|
checkArgs.call(this, 'indexof', args, 2);
|
|
36
36
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
37
37
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
38
|
-
return `(instr(${x}, ${y}) - 1)`; // instr is 1 indexed
|
|
38
|
+
return `(instr(${ x }, ${ y }) - 1)`; // instr is 1 indexed
|
|
39
39
|
},
|
|
40
40
|
matchespattern(signature) {
|
|
41
41
|
const { args } = signature;
|
|
42
42
|
checkArgs.call(this, 'matchespattern', args, 2);
|
|
43
43
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
44
44
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
45
|
-
return `cast((${x} regexp ${y}) as INTEGER)`; // this is a udf, sqlite always returns a REAL w/o the cast
|
|
45
|
+
return `cast((${ x } regexp ${ y }) as INTEGER)`; // this is a udf, sqlite always returns a REAL w/o the cast
|
|
46
|
+
},
|
|
47
|
+
matchesPattern(signature) {
|
|
48
|
+
return oDataFunctions.sqlite.matchespattern.call(this, signature);
|
|
46
49
|
},
|
|
47
50
|
year(signature) {
|
|
48
51
|
const { args } = signature;
|
|
49
52
|
checkArgs.call(this, 'year', args, 1);
|
|
50
53
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
51
|
-
return `cast(strftime('%Y', ${x}) as Integer)`;
|
|
54
|
+
return `cast(strftime('%Y', ${ x }) as Integer)`;
|
|
52
55
|
},
|
|
53
56
|
month(signature) {
|
|
54
57
|
const { args } = signature;
|
|
55
58
|
checkArgs.call(this, 'month', args, 1);
|
|
56
59
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
57
|
-
return `cast(strftime('%m', ${x}) as Integer)`;
|
|
60
|
+
return `cast(strftime('%m', ${ x }) as Integer)`;
|
|
58
61
|
},
|
|
59
62
|
day(signature) {
|
|
60
63
|
const { args } = signature;
|
|
61
64
|
checkArgs.call(this, 'day', args, 1);
|
|
62
65
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
63
|
-
return `cast(strftime('%d', ${x}) as Integer)`;
|
|
66
|
+
return `cast(strftime('%d', ${ x }) as Integer)`;
|
|
64
67
|
},
|
|
65
68
|
hour(signature) {
|
|
66
69
|
const { args } = signature;
|
|
67
70
|
checkArgs.call(this, 'hour', args, 1);
|
|
68
71
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
69
|
-
return `cast(strftime('%H', ${x}) as Integer)`;
|
|
72
|
+
return `cast(strftime('%H', ${ x }) as Integer)`;
|
|
70
73
|
},
|
|
71
74
|
minute(signature) {
|
|
72
75
|
const { args } = signature;
|
|
73
76
|
checkArgs.call(this, 'minute', args, 1);
|
|
74
77
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
75
|
-
return `cast(strftime('%M', ${x}) as Integer)`;
|
|
78
|
+
return `cast(strftime('%M', ${ x }) as Integer)`;
|
|
76
79
|
},
|
|
77
80
|
second(signature) {
|
|
78
81
|
const { args } = signature;
|
|
79
82
|
checkArgs.call(this, 'second', args, 1);
|
|
80
83
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
81
|
-
return `cast(strftime('%S', ${x}) as Integer)`;
|
|
84
|
+
return `cast(strftime('%S', ${ x }) as Integer)`;
|
|
82
85
|
},
|
|
83
86
|
// REVISIT: currently runtimes normalize to milliseconds
|
|
84
87
|
// we could allow this to be more precise
|
|
@@ -86,20 +89,20 @@ const oDataFunctions = {
|
|
|
86
89
|
const { args } = signature;
|
|
87
90
|
checkArgs.call(this, 'fractionalseconds', args, 1);
|
|
88
91
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
89
|
-
return `cast(substr(strftime('%f', ${x}), length(strftime('%f', ${x})) - 3) as REAL)`;
|
|
92
|
+
return `cast(substr(strftime('%f', ${ x }), length(strftime('%f', ${ x })) - 3) as REAL)`;
|
|
90
93
|
},
|
|
91
94
|
// The date(), time(), and datetime() functions all return text, and so their strftime() equivalents are exact.
|
|
92
95
|
time(signature) {
|
|
93
96
|
const { args } = signature;
|
|
94
97
|
checkArgs.call(this, 'time', args, 1);
|
|
95
98
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
96
|
-
return `time(${x})`;
|
|
99
|
+
return `time(${ x })`;
|
|
97
100
|
},
|
|
98
101
|
date(signature) {
|
|
99
102
|
const { args } = signature;
|
|
100
103
|
checkArgs.call(this, 'date', args, 1);
|
|
101
104
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
102
|
-
return `date(${x})`;
|
|
105
|
+
return `date(${ x })`;
|
|
103
106
|
},
|
|
104
107
|
// this could also be a negative number
|
|
105
108
|
// also, parts of the EDM.duration are optional which complicates
|
|
@@ -125,35 +128,38 @@ const oDataFunctions = {
|
|
|
125
128
|
checkArgs.call(this, 'contains', args, 2);
|
|
126
129
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
127
130
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
128
|
-
return `(coalesce(strpos(${x}, ${y}),0) > 0)`;
|
|
131
|
+
return `(coalesce(strpos(${ x }, ${ y }),0) > 0)`;
|
|
129
132
|
},
|
|
130
133
|
startswith(signature) {
|
|
131
134
|
const { args } = signature;
|
|
132
135
|
checkArgs.call(this, 'startswith', args, 2);
|
|
133
136
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
134
137
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
135
|
-
return `coalesce((strpos(${x}, ${y}) = 1), false)`; // strpos is 1 indexed
|
|
138
|
+
return `coalesce((strpos(${ x }, ${ y }) = 1), false)`; // strpos is 1 indexed
|
|
136
139
|
},
|
|
137
140
|
endswith(signature) {
|
|
138
141
|
const { args } = signature;
|
|
139
142
|
checkArgs.call(this, 'endswith', args, 2);
|
|
140
143
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
141
144
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
142
|
-
return `coalesce((substr(${x}, (length(${x}) + 1) - length(${y})) = ${y}), false)`;
|
|
145
|
+
return `coalesce((substr(${ x }, (length(${ x }) + 1) - length(${ y })) = ${ y }), false)`;
|
|
143
146
|
},
|
|
144
147
|
indexof(signature) {
|
|
145
148
|
const { args } = signature;
|
|
146
149
|
checkArgs.call(this, 'indexof', args, 2);
|
|
147
150
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
148
151
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
149
|
-
return `(strpos(${x}, ${y}) - 1)`; // strpos is 1 indexed
|
|
152
|
+
return `(strpos(${ x }, ${ y }) - 1)`; // strpos is 1 indexed
|
|
150
153
|
},
|
|
151
154
|
matchespattern(signature) {
|
|
152
155
|
const { args } = signature;
|
|
153
156
|
checkArgs.call(this, 'matchespattern', args, 2);
|
|
154
157
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
155
158
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
156
|
-
return `regexp_like(${x}, ${y})`;
|
|
159
|
+
return `regexp_like(${ x }, ${ y })`;
|
|
160
|
+
},
|
|
161
|
+
matchesPattern(signature) {
|
|
162
|
+
return oDataFunctions.postgres.matchespattern.call(this, signature);
|
|
157
163
|
},
|
|
158
164
|
// TODO: PG docu recommends to use the "EXTRACT" function for improved precision
|
|
159
165
|
// https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
|
|
@@ -161,37 +167,37 @@ const oDataFunctions = {
|
|
|
161
167
|
const { args } = signature;
|
|
162
168
|
checkArgs.call(this, 'year', args, 1);
|
|
163
169
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
164
|
-
return `cast(date_part('year', ${x}) as Integer)`;
|
|
170
|
+
return `cast(date_part('year', ${ x }) as Integer)`;
|
|
165
171
|
},
|
|
166
172
|
month(signature) {
|
|
167
173
|
const { args } = signature;
|
|
168
174
|
checkArgs.call(this, 'month', args, 1);
|
|
169
175
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
170
|
-
return `cast(date_part('month', ${x}) as Integer)`;
|
|
176
|
+
return `cast(date_part('month', ${ x }) as Integer)`;
|
|
171
177
|
},
|
|
172
178
|
day(signature) {
|
|
173
179
|
const { args } = signature;
|
|
174
180
|
checkArgs.call(this, 'day', args, 1);
|
|
175
181
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
176
|
-
return `cast(date_part('day', ${x}) as Integer)`;
|
|
182
|
+
return `cast(date_part('day', ${ x }) as Integer)`;
|
|
177
183
|
},
|
|
178
184
|
hour(signature) {
|
|
179
185
|
const { args } = signature;
|
|
180
186
|
checkArgs.call(this, 'hour', args, 1);
|
|
181
187
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
182
|
-
return `cast(date_part('hour', ${x}) as Integer)`;
|
|
188
|
+
return `cast(date_part('hour', ${ x }) as Integer)`;
|
|
183
189
|
},
|
|
184
190
|
minute(signature) {
|
|
185
191
|
const { args } = signature;
|
|
186
192
|
checkArgs.call(this, 'minute', args, 1);
|
|
187
193
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
188
|
-
return `cast(date_part('minute', ${x}) as Integer)`;
|
|
194
|
+
return `cast(date_part('minute', ${ x }) as Integer)`;
|
|
189
195
|
},
|
|
190
196
|
second(signature) {
|
|
191
197
|
const { args } = signature;
|
|
192
198
|
checkArgs.call(this, 'second', args, 1);
|
|
193
199
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
194
|
-
return `cast(floor(date_part('second', ${x})) as Integer)`;
|
|
200
|
+
return `cast(floor(date_part('second', ${ x })) as Integer)`;
|
|
195
201
|
},
|
|
196
202
|
// REVISIT: currently runtimes normalize to milliseconds
|
|
197
203
|
// we could allow this to be more precise
|
|
@@ -199,19 +205,19 @@ const oDataFunctions = {
|
|
|
199
205
|
const { args } = signature;
|
|
200
206
|
checkArgs.call(this, 'fractionalseconds', args, 1);
|
|
201
207
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
202
|
-
return `cast(date_part('second', ${x}) - floor(date_part('second', ${x})) AS DECIMAL(3,3))`;
|
|
208
|
+
return `cast(date_part('second', ${ x }) - floor(date_part('second', ${ x })) AS DECIMAL(3,3))`;
|
|
203
209
|
},
|
|
204
210
|
time(signature) {
|
|
205
211
|
const { args } = signature;
|
|
206
212
|
checkArgs.call(this, 'time', args, 1);
|
|
207
213
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
208
|
-
return `to_char(${x}, 'HH24:MI:SS')::TIME`;
|
|
214
|
+
return `to_char(${ x }, 'HH24:MI:SS')::TIME`;
|
|
209
215
|
},
|
|
210
216
|
date(signature) {
|
|
211
217
|
const { args } = signature;
|
|
212
218
|
checkArgs.call(this, 'date', args, 1);
|
|
213
219
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
214
|
-
return `${x}::DATE`;
|
|
220
|
+
return `${ x }::DATE`;
|
|
215
221
|
},
|
|
216
222
|
},
|
|
217
223
|
// https://help.sap.com/docs/HANA_SERVICE_CF/7c78579ce9b14a669c1f3295b0d8ca16/f12b86a6284c4aeeb449e57eb5dd3ebd.html?locale=en-US
|
|
@@ -226,31 +232,31 @@ const oDataFunctions = {
|
|
|
226
232
|
// While CONTAINS() looks like a function because of its syntax,
|
|
227
233
|
// it is classified as a predicate because it is designed to evaluate a condition
|
|
228
234
|
// and return a Boolean result.
|
|
229
|
-
return `CONTAINS(${x}, ${y}, ${z})`;
|
|
235
|
+
return `CONTAINS(${ x }, ${ y }, ${ z })`;
|
|
230
236
|
}
|
|
231
237
|
|
|
232
|
-
return `(CASE WHEN coalesce(locate(${this.renderArgs(signature)}),0)>0 THEN TRUE ELSE FALSE END)`;
|
|
238
|
+
return `(CASE WHEN coalesce(locate(${ this.renderArgs(signature) }),0)>0 THEN TRUE ELSE FALSE END)`;
|
|
233
239
|
},
|
|
234
240
|
startswith(signature) {
|
|
235
241
|
const { args } = signature;
|
|
236
242
|
checkArgs.call(this, 'startswith', args, 2);
|
|
237
243
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
238
244
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
239
|
-
return `(CASE WHEN locate(${x}, ${y}) = 1 THEN TRUE ELSE FALSE END)`;
|
|
245
|
+
return `(CASE WHEN locate(${ x }, ${ y }) = 1 THEN TRUE ELSE FALSE END)`;
|
|
240
246
|
}, // locate is 1 indexed
|
|
241
247
|
endswith(signature) {
|
|
242
248
|
const { args } = signature;
|
|
243
249
|
checkArgs.call(this, 'endswith', args, 2);
|
|
244
250
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
245
251
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
246
|
-
return `(CASE WHEN substring(${x}, (length(${x}) + 1) - length(${y})) = ${y} THEN TRUE ELSE FALSE END)`;
|
|
252
|
+
return `(CASE WHEN substring(${ x }, (length(${ x }) + 1) - length(${ y })) = ${ y } THEN TRUE ELSE FALSE END)`;
|
|
247
253
|
},
|
|
248
254
|
indexof(signature) {
|
|
249
255
|
const { args } = signature;
|
|
250
256
|
checkArgs.call(this, 'indexof', args, 2);
|
|
251
257
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
252
258
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
253
|
-
return `(locate(${x}, ${y}) - 1)`; // locate is 1 indexed
|
|
259
|
+
return `(locate(${ x }, ${ y }) - 1)`; // locate is 1 indexed
|
|
254
260
|
},
|
|
255
261
|
matchespattern(signature) {
|
|
256
262
|
// case … when only works as column expression (not in where)
|
|
@@ -259,43 +265,46 @@ const oDataFunctions = {
|
|
|
259
265
|
checkArgs.call(this, 'matchespattern', args, 2);
|
|
260
266
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
261
267
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
262
|
-
return `(CASE WHEN ${x} LIKE_REGEXPR ${y} THEN TRUE ELSE FALSE END)`;
|
|
268
|
+
return `(CASE WHEN ${ x } LIKE_REGEXPR ${ y } THEN TRUE ELSE FALSE END)`;
|
|
269
|
+
},
|
|
270
|
+
matchesPattern(signature) {
|
|
271
|
+
return oDataFunctions.hana.matchespattern.call(this, signature);
|
|
263
272
|
},
|
|
264
273
|
year(signature) {
|
|
265
274
|
const { args } = signature;
|
|
266
275
|
checkArgs.call(this, 'year', args, 1);
|
|
267
276
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
268
|
-
return `year(${x})`;
|
|
277
|
+
return `year(${ x })`;
|
|
269
278
|
},
|
|
270
279
|
month(signature) {
|
|
271
280
|
const { args } = signature;
|
|
272
281
|
checkArgs.call(this, 'month', args, 1);
|
|
273
282
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
274
|
-
return `month(${x})`;
|
|
283
|
+
return `month(${ x })`;
|
|
275
284
|
},
|
|
276
285
|
day(signature) {
|
|
277
286
|
const { args } = signature;
|
|
278
287
|
checkArgs.call(this, 'day', args, 1);
|
|
279
288
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
280
|
-
return `dayofmonth(${x})`;
|
|
289
|
+
return `dayofmonth(${ x })`;
|
|
281
290
|
},
|
|
282
291
|
hour(signature) {
|
|
283
292
|
const { args } = signature;
|
|
284
293
|
checkArgs.call(this, 'hour', args, 1);
|
|
285
294
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
286
|
-
return `hour(${x})`;
|
|
295
|
+
return `hour(${ x })`;
|
|
287
296
|
},
|
|
288
297
|
minute(signature) {
|
|
289
298
|
const { args } = signature;
|
|
290
299
|
checkArgs.call(this, 'minute', args, 1);
|
|
291
300
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
292
|
-
return `minute(${x})`;
|
|
301
|
+
return `minute(${ x })`;
|
|
293
302
|
},
|
|
294
303
|
second(signature) {
|
|
295
304
|
const { args } = signature;
|
|
296
305
|
checkArgs.call(this, 'second', args, 1);
|
|
297
306
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
298
|
-
return `to_integer(second(${x}))`;
|
|
307
|
+
return `to_integer(second(${ x }))`;
|
|
299
308
|
},
|
|
300
309
|
// REVISIT: currently runtimes normalize to milliseconds
|
|
301
310
|
// we could allow this to be more precise
|
|
@@ -303,19 +312,19 @@ const oDataFunctions = {
|
|
|
303
312
|
const { args } = signature;
|
|
304
313
|
checkArgs.call(this, 'fractionalseconds', args, 1);
|
|
305
314
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
306
|
-
return `(to_decimal(second(${x}),5,3) - to_integer(second(${x})))`;
|
|
315
|
+
return `(to_decimal(second(${ x }),5,3) - to_integer(second(${ x })))`;
|
|
307
316
|
},
|
|
308
317
|
time(signature) {
|
|
309
318
|
const { args } = signature;
|
|
310
319
|
checkArgs.call(this, 'time', args, 1);
|
|
311
320
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
312
|
-
return `to_time(${x})`;
|
|
321
|
+
return `to_time(${ x })`;
|
|
313
322
|
},
|
|
314
323
|
date(signature) {
|
|
315
324
|
const { args } = signature;
|
|
316
325
|
checkArgs.call(this, 'date', args, 1);
|
|
317
326
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
318
|
-
return `to_date(${x})`;
|
|
327
|
+
return `to_date(${ x })`;
|
|
319
328
|
},
|
|
320
329
|
},
|
|
321
330
|
// https://www.h2database.com/html/functions.html
|
|
@@ -327,7 +336,7 @@ const oDataFunctions = {
|
|
|
327
336
|
args.reverse();
|
|
328
337
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
329
338
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
330
|
-
return `(coalesce(locate(${x}, ${y}),0) > 0)`;
|
|
339
|
+
return `(coalesce(locate(${ x }, ${ y }),0) > 0)`;
|
|
331
340
|
},
|
|
332
341
|
startswith(signature) {
|
|
333
342
|
const args = [ ...signature.args ];
|
|
@@ -336,14 +345,14 @@ const oDataFunctions = {
|
|
|
336
345
|
args.reverse();
|
|
337
346
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
338
347
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
339
|
-
return `coalesce((locate(${x}, ${y}) = 1), false)`; // locate is 1 indexed
|
|
348
|
+
return `coalesce((locate(${ x }, ${ y }) = 1), false)`; // locate is 1 indexed
|
|
340
349
|
},
|
|
341
350
|
endswith(signature) {
|
|
342
351
|
const { args } = signature;
|
|
343
352
|
checkArgs.call(this, 'endswith', args, 2);
|
|
344
353
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
345
354
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
346
|
-
return `coalesce((substring(${x} FROM (char_length(${x}) + 1) - char_length(${y})) = ${y}), false)`;
|
|
355
|
+
return `coalesce((substring(${ x } FROM (char_length(${ x }) + 1) - char_length(${ y })) = ${ y }), false)`;
|
|
347
356
|
},
|
|
348
357
|
substring(signature) {
|
|
349
358
|
const { args } = signature;
|
|
@@ -354,8 +363,8 @@ const oDataFunctions = {
|
|
|
354
363
|
? this.renderArgs({ ...signature, args: [ args[2] ] })
|
|
355
364
|
: null;
|
|
356
365
|
return z
|
|
357
|
-
? `substring(${x} FROM CASE WHEN ${y} < 0 THEN char_length(${x}) + ${y} + 1 ELSE ${y} + 1 END FOR ${z})`
|
|
358
|
-
: `substring(${x} FROM CASE WHEN ${y} < 0 THEN char_length(${x}) + ${y} + 1 ELSE ${y} + 1 END)`;
|
|
366
|
+
? `substring(${ x } FROM CASE WHEN ${ y } < 0 THEN char_length(${ x }) + ${ y } + 1 ELSE ${ y } + 1 END FOR ${ z })`
|
|
367
|
+
: `substring(${ x } FROM CASE WHEN ${ y } < 0 THEN char_length(${ x }) + ${ y } + 1 ELSE ${ y } + 1 END)`;
|
|
359
368
|
},
|
|
360
369
|
// char_length is preferred over length -> REVISIT: returns a BIGINT, is this ok?
|
|
361
370
|
// https://www.h2database.com/html/functions.html#char_length
|
|
@@ -363,7 +372,7 @@ const oDataFunctions = {
|
|
|
363
372
|
const { args } = signature;
|
|
364
373
|
checkArgs.call(this, 'length', args, 1);
|
|
365
374
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
366
|
-
return `cast(char_length(${x}) as Integer)`;
|
|
375
|
+
return `cast(char_length(${ x }) as Integer)`;
|
|
367
376
|
},
|
|
368
377
|
indexof(signature) {
|
|
369
378
|
const args = [ ...signature.args ];
|
|
@@ -372,50 +381,53 @@ const oDataFunctions = {
|
|
|
372
381
|
args.reverse();
|
|
373
382
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
374
383
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
375
|
-
return `(locate(${x}, ${y}) - 1)`; // locate is 1 indexed
|
|
384
|
+
return `(locate(${ x }, ${ y }) - 1)`; // locate is 1 indexed
|
|
376
385
|
},
|
|
377
386
|
matchespattern(signature) {
|
|
378
387
|
const { args } = signature;
|
|
379
388
|
checkArgs.call(this, 'matchespattern', args, 2);
|
|
380
389
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
381
390
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
382
|
-
return `regexp_like(${x}, ${y})`;
|
|
391
|
+
return `regexp_like(${ x }, ${ y })`;
|
|
392
|
+
},
|
|
393
|
+
matchesPattern(signature) {
|
|
394
|
+
return oDataFunctions.h2.matchespattern.call(this, signature);
|
|
383
395
|
},
|
|
384
396
|
year(signature) {
|
|
385
397
|
const { args } = signature;
|
|
386
398
|
checkArgs.call(this, 'year', args, 1);
|
|
387
399
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
388
|
-
return `extract(YEAR FROM ${x})`;
|
|
400
|
+
return `extract(YEAR FROM ${ x })`;
|
|
389
401
|
},
|
|
390
402
|
month(signature) {
|
|
391
403
|
const { args } = signature;
|
|
392
404
|
checkArgs.call(this, 'month', args, 1);
|
|
393
405
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
394
|
-
return `extract(MONTH FROM ${x})`;
|
|
406
|
+
return `extract(MONTH FROM ${ x })`;
|
|
395
407
|
},
|
|
396
408
|
day(signature) {
|
|
397
409
|
const { args } = signature;
|
|
398
410
|
checkArgs.call(this, 'day', args, 1);
|
|
399
411
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
400
|
-
return `extract(DAY FROM ${x})`;
|
|
412
|
+
return `extract(DAY FROM ${ x })`;
|
|
401
413
|
},
|
|
402
414
|
hour(signature) {
|
|
403
415
|
const { args } = signature;
|
|
404
416
|
checkArgs.call(this, 'hour', args, 1);
|
|
405
417
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
406
|
-
return `extract(HOUR FROM ${x})`;
|
|
418
|
+
return `extract(HOUR FROM ${ x })`;
|
|
407
419
|
},
|
|
408
420
|
minute(signature) {
|
|
409
421
|
const { args } = signature;
|
|
410
422
|
checkArgs.call(this, 'minute', args, 1);
|
|
411
423
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
412
|
-
return `extract(MINUTE FROM ${x})`;
|
|
424
|
+
return `extract(MINUTE FROM ${ x })`;
|
|
413
425
|
},
|
|
414
426
|
second(signature) {
|
|
415
427
|
const { args } = signature;
|
|
416
428
|
checkArgs.call(this, 'second', args, 1);
|
|
417
429
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
418
|
-
return `extract(SECOND FROM ${x})`;
|
|
430
|
+
return `extract(SECOND FROM ${ x })`;
|
|
419
431
|
},
|
|
420
432
|
// REVISIT: currently runtimes normalize to milliseconds
|
|
421
433
|
// we could allow this to be more precise
|
|
@@ -423,19 +435,19 @@ const oDataFunctions = {
|
|
|
423
435
|
const { args } = signature;
|
|
424
436
|
checkArgs.call(this, 'fractionalseconds', args, 1);
|
|
425
437
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
426
|
-
return `cast(extract(MILLISECOND FROM ${x}) / 1000.0 AS NUMERIC(3,3))`;
|
|
438
|
+
return `cast(extract(MILLISECOND FROM ${ x }) / 1000.0 AS NUMERIC(3,3))`;
|
|
427
439
|
},
|
|
428
440
|
time(signature) {
|
|
429
441
|
const { args } = signature;
|
|
430
442
|
checkArgs.call(this, 'time', args, 1);
|
|
431
443
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
432
|
-
return `cast(${x} AS TIME)`;
|
|
444
|
+
return `cast(${ x } AS TIME)`;
|
|
433
445
|
},
|
|
434
446
|
date(signature) {
|
|
435
447
|
const { args } = signature;
|
|
436
448
|
checkArgs.call(this, 'date', args, 1);
|
|
437
449
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
438
|
-
return `cast(${x} AS DATE)`;
|
|
450
|
+
return `cast(${ x } AS DATE)`;
|
|
439
451
|
},
|
|
440
452
|
},
|
|
441
453
|
common: {
|
|
@@ -449,25 +461,25 @@ const oDataFunctions = {
|
|
|
449
461
|
return acc;
|
|
450
462
|
}, []);
|
|
451
463
|
const res = this.renderArgs({ signature, ...{ args: [ args ] } });
|
|
452
|
-
return `(${res})`;
|
|
464
|
+
return `(${ res })`;
|
|
453
465
|
},
|
|
454
466
|
ceiling(signature) {
|
|
455
467
|
const { args } = signature;
|
|
456
468
|
checkArgs.call(this, 'ceiling', args, 1);
|
|
457
469
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
458
|
-
return `ceil(${x})`;
|
|
470
|
+
return `ceil(${ x })`;
|
|
459
471
|
},
|
|
460
472
|
floor(signature) {
|
|
461
473
|
const { args } = signature;
|
|
462
474
|
checkArgs.call(this, 'floor', args, 1);
|
|
463
475
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
464
|
-
return `floor(${x})`;
|
|
476
|
+
return `floor(${ x })`;
|
|
465
477
|
},
|
|
466
478
|
trim(signature) {
|
|
467
479
|
const { args } = signature;
|
|
468
480
|
checkArgs.call(this, 'trim', args, 1);
|
|
469
481
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
470
|
-
return `trim(${x})`;
|
|
482
|
+
return `trim(${ x })`;
|
|
471
483
|
},
|
|
472
484
|
// SAP HANA, sqlite and postgres share the same implementation
|
|
473
485
|
substring(signature) {
|
|
@@ -479,59 +491,59 @@ const oDataFunctions = {
|
|
|
479
491
|
? this.renderArgs({ ...signature, args: [ args[2] ] })
|
|
480
492
|
: null;
|
|
481
493
|
return z
|
|
482
|
-
? `substr(${x}, CASE WHEN ${y} < 0 THEN length(${x}) + ${y} + 1 ELSE ${y} + 1 END, ${z})`
|
|
483
|
-
: `substr(${x}, CASE WHEN ${y} < 0 THEN length(${x}) + ${y} + 1 ELSE ${y} + 1 END)`;
|
|
494
|
+
? `substr(${ x }, CASE WHEN ${ y } < 0 THEN length(${ x }) + ${ y } + 1 ELSE ${ y } + 1 END, ${ z })`
|
|
495
|
+
: `substr(${ x }, CASE WHEN ${ y } < 0 THEN length(${ x }) + ${ y } + 1 ELSE ${ y } + 1 END)`;
|
|
484
496
|
},
|
|
485
497
|
min(signature) {
|
|
486
498
|
const { args } = signature;
|
|
487
499
|
checkArgs.call(this, 'min', args, 1);
|
|
488
500
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
489
|
-
return `min(${x})`;
|
|
501
|
+
return `min(${ x })`;
|
|
490
502
|
},
|
|
491
503
|
max(signature) {
|
|
492
504
|
const { args } = signature;
|
|
493
505
|
checkArgs.call(this, 'max', args, 1);
|
|
494
506
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
495
|
-
return `max(${x})`;
|
|
507
|
+
return `max(${ x })`;
|
|
496
508
|
},
|
|
497
509
|
sum(signature) {
|
|
498
510
|
const { args } = signature;
|
|
499
511
|
checkArgs.call(this, 'sum', args, 1);
|
|
500
512
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
501
|
-
return `sum(${x})`;
|
|
513
|
+
return `sum(${ x })`;
|
|
502
514
|
},
|
|
503
515
|
count(signature) {
|
|
504
516
|
const { args } = signature;
|
|
505
517
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
506
|
-
return `count(${x || '*'})`;
|
|
518
|
+
return `count(${ x || '*' })`;
|
|
507
519
|
},
|
|
508
520
|
countdistinct(signature) {
|
|
509
521
|
const { args } = signature;
|
|
510
|
-
return `count(distinct ${args.length > 0 ? this.renderArgs(signature) : "'*'"})`;
|
|
522
|
+
return `count(distinct ${ args.length > 0 ? this.renderArgs(signature) : "'*'" })`;
|
|
511
523
|
},
|
|
512
524
|
average(signature) {
|
|
513
525
|
const { args } = signature;
|
|
514
526
|
checkArgs.call(this, 'average', args, 1);
|
|
515
527
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
516
|
-
return `avg(${x})`;
|
|
528
|
+
return `avg(${ x })`;
|
|
517
529
|
},
|
|
518
530
|
length(signature) {
|
|
519
531
|
const { args } = signature;
|
|
520
532
|
checkArgs.call(this, 'length', args, 1);
|
|
521
533
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
522
|
-
return `length(${x})`;
|
|
534
|
+
return `length(${ x })`;
|
|
523
535
|
},
|
|
524
536
|
tolower(signature) {
|
|
525
537
|
const { args } = signature;
|
|
526
538
|
checkArgs.call(this, 'tolower', args, 1);
|
|
527
539
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
528
|
-
return `lower(${x})`;
|
|
540
|
+
return `lower(${ x })`;
|
|
529
541
|
},
|
|
530
542
|
toupper(signature) {
|
|
531
543
|
const { args } = signature;
|
|
532
544
|
checkArgs.call(this, 'toupper', args, 1);
|
|
533
545
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
534
|
-
return `upper(${x})`;
|
|
546
|
+
return `upper(${ x })`;
|
|
535
547
|
},
|
|
536
548
|
// eslint-disable-next-line no-unused-vars
|
|
537
549
|
maxdatetime(signature) {
|
|
@@ -563,7 +575,7 @@ const hanaFunctions = {
|
|
|
563
575
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
564
576
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
565
577
|
// 1 day = 24h*60m*60s*10'000'000 = 864'000'000'000 nano100
|
|
566
|
-
return `CAST(((julianday(${y}) - julianday(${x})) * 864000000000) as INTEGER)`;
|
|
578
|
+
return `CAST(((julianday(${ y }) - julianday(${ x })) * 864000000000) as INTEGER)`;
|
|
567
579
|
},
|
|
568
580
|
seconds_between(signature) {
|
|
569
581
|
const { args } = signature;
|
|
@@ -571,7 +583,7 @@ const hanaFunctions = {
|
|
|
571
583
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
572
584
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
573
585
|
|
|
574
|
-
return `CAST(strftime('%s', ${y}) - strftime('%s', ${x}) AS INTEGER)`;
|
|
586
|
+
return `CAST(strftime('%s', ${ y }) - strftime('%s', ${ x }) AS INTEGER)`;
|
|
575
587
|
},
|
|
576
588
|
days_between(signature) {
|
|
577
589
|
const { args } = signature;
|
|
@@ -579,7 +591,7 @@ const hanaFunctions = {
|
|
|
579
591
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
580
592
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
581
593
|
|
|
582
|
-
return `(CASE WHEN (strftime('%s', ${y}) - strftime('%s', ${x})) < 86400 AND (strftime('%s', ${y}) - strftime('%s', ${x})) > -86400 THEN 0 ELSE CAST((strftime('%s', ${y}) - strftime('%s', ${x})) / 86400 AS INTEGER) END)`;
|
|
594
|
+
return `(CASE WHEN (strftime('%s', ${ y }) - strftime('%s', ${ x })) < 86400 AND (strftime('%s', ${ y }) - strftime('%s', ${ x })) > -86400 THEN 0 ELSE CAST((strftime('%s', ${ y }) - strftime('%s', ${ x })) / 86400 AS INTEGER) END)`;
|
|
583
595
|
},
|
|
584
596
|
/**
|
|
585
597
|
* Calculates the difference in months between two dates, `x` and `y`, with a correction for partial months.
|
|
@@ -620,20 +632,20 @@ const hanaFunctions = {
|
|
|
620
632
|
const res = `
|
|
621
633
|
(
|
|
622
634
|
(
|
|
623
|
-
(CAST(strftime('%Y', ${y}) AS Integer) - CAST(strftime('%Y', ${x}) AS Integer)) * 12
|
|
635
|
+
(CAST(strftime('%Y', ${ y }) AS Integer) - CAST(strftime('%Y', ${ x }) AS Integer)) * 12
|
|
624
636
|
)
|
|
625
637
|
+
|
|
626
638
|
(
|
|
627
|
-
CAST(strftime('%m', ${y}) AS Integer) - CAST(strftime('%m', ${x}) AS Integer)
|
|
639
|
+
CAST(strftime('%m', ${ y }) AS Integer) - CAST(strftime('%m', ${ x }) AS Integer)
|
|
628
640
|
)
|
|
629
641
|
+
|
|
630
642
|
(
|
|
631
643
|
CASE
|
|
632
644
|
/* For backward intervals: if the composite (day + time) of y is greater than x, add 1. */
|
|
633
|
-
WHEN CAST(strftime('%Y%m', ${y}) AS Integer) < CAST(strftime('%Y%m', ${x}) AS Integer)
|
|
634
|
-
THEN (CAST(strftime('%d%H%M%S%f0000', ${y}) AS Integer) > CAST(strftime('%d%H%M%S%f0000', ${x}) AS Integer))
|
|
645
|
+
WHEN CAST(strftime('%Y%m', ${ y }) AS Integer) < CAST(strftime('%Y%m', ${ x }) AS Integer)
|
|
646
|
+
THEN (CAST(strftime('%d%H%M%S%f0000', ${ y }) AS Integer) > CAST(strftime('%d%H%M%S%f0000', ${ x }) AS Integer))
|
|
635
647
|
/* For forward intervals: if the composite of y is less than x, subtract 1. */
|
|
636
|
-
ELSE (CAST(strftime('%d%H%M%S%f0000', ${y}) AS Integer) < CAST(strftime('%d%H%M%S%f0000', ${x}) AS Integer)) * -1
|
|
648
|
+
ELSE (CAST(strftime('%d%H%M%S%f0000', ${ y }) AS Integer) < CAST(strftime('%d%H%M%S%f0000', ${ x }) AS Integer)) * -1
|
|
637
649
|
END
|
|
638
650
|
)
|
|
639
651
|
)
|
|
@@ -644,7 +656,7 @@ const hanaFunctions = {
|
|
|
644
656
|
years_between(signature) {
|
|
645
657
|
const { args } = signature;
|
|
646
658
|
checkArgs.call(this, 'years_between', args, 2);
|
|
647
|
-
return `floor((${hanaFunctions.sqlite.months_between.call(this, signature)}) / 12)`;
|
|
659
|
+
return `floor((${ hanaFunctions.sqlite.months_between.call(this, signature) }) / 12)`;
|
|
648
660
|
},
|
|
649
661
|
},
|
|
650
662
|
postgres: {
|
|
@@ -654,7 +666,7 @@ const hanaFunctions = {
|
|
|
654
666
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
655
667
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
656
668
|
// make sure to cast NUMERIC to BIGINT (corresponds to cds.Int64)
|
|
657
|
-
return `(EXTRACT(EPOCH FROM (${y}) - (${x})) * 10000000)::BIGINT`;
|
|
669
|
+
return `(EXTRACT(EPOCH FROM (${ y }) - (${ x })) * 10000000)::BIGINT`;
|
|
658
670
|
},
|
|
659
671
|
seconds_between(signature) {
|
|
660
672
|
const { args } = signature;
|
|
@@ -662,14 +674,14 @@ const hanaFunctions = {
|
|
|
662
674
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
663
675
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
664
676
|
|
|
665
|
-
return `EXTRACT(EPOCH FROM (${y}) - (${x}))::BIGINT`;
|
|
677
|
+
return `EXTRACT(EPOCH FROM (${ y }) - (${ x }))::BIGINT`;
|
|
666
678
|
},
|
|
667
679
|
days_between(signature) {
|
|
668
680
|
const { args } = signature;
|
|
669
681
|
checkArgs.call(this, 'days_between', args, 2);
|
|
670
682
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
671
683
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
672
|
-
return `EXTRACT(DAY FROM ${y}::timestamp - ${x}::timestamp)::integer`;
|
|
684
|
+
return `EXTRACT(DAY FROM ${ y }::timestamp - ${ x }::timestamp)::integer`;
|
|
673
685
|
},
|
|
674
686
|
months_between(signature) {
|
|
675
687
|
const { args } = signature;
|
|
@@ -677,12 +689,12 @@ const hanaFunctions = {
|
|
|
677
689
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
678
690
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
679
691
|
|
|
680
|
-
return `(EXTRACT(YEAR FROM AGE(${y}, ${x})) * 12 + EXTRACT(MONTH FROM AGE(${y}, ${x})))::INTEGER`;
|
|
692
|
+
return `(EXTRACT(YEAR FROM AGE(${ y }, ${ x })) * 12 + EXTRACT(MONTH FROM AGE(${ y }, ${ x })))::INTEGER`;
|
|
681
693
|
},
|
|
682
694
|
years_between(signature) {
|
|
683
695
|
const { args } = signature;
|
|
684
696
|
checkArgs.call(this, 'years_between', args, 2);
|
|
685
|
-
return `floor((${hanaFunctions.postgres.months_between.call(this, signature)}) / 12)::INTEGER`;
|
|
697
|
+
return `floor((${ hanaFunctions.postgres.months_between.call(this, signature) }) / 12)::INTEGER`;
|
|
686
698
|
},
|
|
687
699
|
},
|
|
688
700
|
h2: {
|
|
@@ -692,7 +704,7 @@ const hanaFunctions = {
|
|
|
692
704
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
693
705
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
694
706
|
|
|
695
|
-
return `CAST(DATEDIFF('MICROSECOND', ${x}, ${y}) * 10 AS BIGINT)`;
|
|
707
|
+
return `CAST(DATEDIFF('MICROSECOND', ${ x }, ${ y }) * 10 AS BIGINT)`;
|
|
696
708
|
},
|
|
697
709
|
seconds_between(signature) {
|
|
698
710
|
const { args } = signature;
|
|
@@ -700,14 +712,14 @@ const hanaFunctions = {
|
|
|
700
712
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
701
713
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
702
714
|
|
|
703
|
-
return `CAST(DATEDIFF('SECOND', ${x}, ${y}) AS BIGINT)`;
|
|
715
|
+
return `CAST(DATEDIFF('SECOND', ${ x }, ${ y }) AS BIGINT)`;
|
|
704
716
|
},
|
|
705
717
|
days_between(signature) {
|
|
706
718
|
const { args } = signature;
|
|
707
719
|
checkArgs.call(this, 'days_between', args, 2);
|
|
708
720
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
709
721
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
710
|
-
return `CASE WHEN ABS(DATEDIFF('SECOND', ${x}, ${y})) < 86400 THEN 0 ELSE CAST(FLOOR(DATEDIFF('SECOND', ${x}, ${y}) / 86400) AS INTEGER) END`;
|
|
722
|
+
return `CASE WHEN ABS(DATEDIFF('SECOND', ${ x }, ${ y })) < 86400 THEN 0 ELSE CAST(FLOOR(DATEDIFF('SECOND', ${ x }, ${ y }) / 86400) AS INTEGER) END`;
|
|
711
723
|
},
|
|
712
724
|
/**
|
|
713
725
|
* Uses DATEDIFF('MONTH') and then applies a partial-month correction for day-of-month boundaries in both
|
|
@@ -722,14 +734,14 @@ const hanaFunctions = {
|
|
|
722
734
|
|
|
723
735
|
const res = `
|
|
724
736
|
CAST(
|
|
725
|
-
DATEDIFF('MONTH', ${x}, ${y})
|
|
737
|
+
DATEDIFF('MONTH', ${ x }, ${ y })
|
|
726
738
|
+ CASE
|
|
727
|
-
WHEN DATEDIFF('DAY', ${x}, ${y}) >= 0
|
|
728
|
-
AND EXTRACT(DAY FROM ${y}) < EXTRACT(DAY FROM ${x})
|
|
739
|
+
WHEN DATEDIFF('DAY', ${ x }, ${ y }) >= 0
|
|
740
|
+
AND EXTRACT(DAY FROM ${ y }) < EXTRACT(DAY FROM ${ x })
|
|
729
741
|
THEN -1
|
|
730
742
|
|
|
731
|
-
WHEN DATEDIFF('DAY', ${x}, ${y}) < 0
|
|
732
|
-
AND EXTRACT(DAY FROM ${y}) > EXTRACT(DAY FROM ${x})
|
|
743
|
+
WHEN DATEDIFF('DAY', ${ x }, ${ y }) < 0
|
|
744
|
+
AND EXTRACT(DAY FROM ${ y }) > EXTRACT(DAY FROM ${ x })
|
|
733
745
|
THEN 1
|
|
734
746
|
|
|
735
747
|
ELSE 0
|
|
@@ -742,7 +754,7 @@ const hanaFunctions = {
|
|
|
742
754
|
years_between(signature) {
|
|
743
755
|
const { args } = signature;
|
|
744
756
|
checkArgs.call(this, 'years_between', args, 2);
|
|
745
|
-
return `floor((${hanaFunctions.h2.months_between.call(this, signature)}) / 12)`;
|
|
757
|
+
return `floor((${ hanaFunctions.h2.months_between.call(this, signature) }) / 12)`;
|
|
746
758
|
},
|
|
747
759
|
},
|
|
748
760
|
common: {},
|
|
@@ -754,7 +766,7 @@ const hanaFunctions = {
|
|
|
754
766
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
755
767
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
756
768
|
|
|
757
|
-
return `nano100_between(${x}, ${y})`;
|
|
769
|
+
return `nano100_between(${ x }, ${ y })`;
|
|
758
770
|
},
|
|
759
771
|
seconds_between(signature) {
|
|
760
772
|
const { args } = signature;
|
|
@@ -762,14 +774,14 @@ const hanaFunctions = {
|
|
|
762
774
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
763
775
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
764
776
|
|
|
765
|
-
return `seconds_between(${x}, ${y})`;
|
|
777
|
+
return `seconds_between(${ x }, ${ y })`;
|
|
766
778
|
},
|
|
767
779
|
days_between(signature) {
|
|
768
780
|
const { args } = signature;
|
|
769
781
|
checkArgs.call(this, 'days_between', args, 2);
|
|
770
782
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
771
783
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
772
|
-
return `days_between(${x}, ${y})`;
|
|
784
|
+
return `days_between(${ x }, ${ y })`;
|
|
773
785
|
},
|
|
774
786
|
months_between(signature) {
|
|
775
787
|
const { args } = signature;
|
|
@@ -777,12 +789,12 @@ const hanaFunctions = {
|
|
|
777
789
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
778
790
|
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
779
791
|
|
|
780
|
-
return `months_between(${x}, ${y})`;
|
|
792
|
+
return `months_between(${ x }, ${ y })`;
|
|
781
793
|
},
|
|
782
794
|
years_between(signature) {
|
|
783
795
|
const { args } = signature;
|
|
784
796
|
checkArgs.call(this, 'years_between', args, 2);
|
|
785
|
-
return `years_between(${this.renderArgs(signature)})`;
|
|
797
|
+
return `years_between(${ this.renderArgs(signature) })`;
|
|
786
798
|
},
|
|
787
799
|
},
|
|
788
800
|
};
|