@abedmurrar/objection 4.0.0-alpha.0 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -67
- package/lib/index.mjs +6 -0
- package/lib/initialize.js +6 -9
- package/lib/model/AjvValidator.js +235 -282
- package/lib/model/Model.js +653 -823
- package/lib/model/ModifierNotFoundError.js +5 -7
- package/lib/model/NotFoundError.js +14 -18
- package/lib/model/RelationDoesNotExistError.js +6 -9
- package/lib/model/ValidationError.js +33 -41
- package/lib/model/Validator.js +15 -21
- package/lib/model/getModel.js +1 -3
- package/lib/model/graph/ModelGraph.js +44 -64
- package/lib/model/graph/ModelGraphBuilder.js +164 -217
- package/lib/model/graph/ModelGraphEdge.js +31 -43
- package/lib/model/graph/ModelGraphNode.js +192 -231
- package/lib/model/inheritModel.js +9 -18
- package/lib/model/modelBindKnex.js +48 -62
- package/lib/model/modelClone.js +79 -98
- package/lib/model/modelColPropMap.js +16 -26
- package/lib/model/modelConcurrency.js +24 -0
- package/lib/model/modelId.js +44 -49
- package/lib/model/modelJsonAttributes.js +56 -76
- package/lib/model/modelParseRelations.js +68 -67
- package/lib/model/modelQueryProps.js +76 -107
- package/lib/model/modelSet.js +92 -112
- package/lib/model/modelTableMetadata.js +60 -72
- package/lib/model/modelToJson.js +120 -150
- package/lib/model/modelUtils.js +30 -37
- package/lib/model/modelValidate.js +34 -42
- package/lib/model/modelValues.js +78 -91
- package/lib/model/modelVisitor.js +22 -29
- package/lib/objection.js +42 -67
- package/lib/queryBuilder/FunctionBuilder.js +231 -279
- package/lib/queryBuilder/InternalOptions.js +19 -24
- package/lib/queryBuilder/JoinBuilder.js +116 -149
- package/lib/queryBuilder/QueryBuilder.js +1009 -1271
- package/lib/queryBuilder/QueryBuilderBase.js +647 -865
- package/lib/queryBuilder/QueryBuilderContext.js +14 -21
- package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
- package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
- package/lib/queryBuilder/RawBuilder.js +58 -73
- package/lib/queryBuilder/ReferenceBuilder.js +232 -270
- package/lib/queryBuilder/RelationExpression.js +322 -380
- package/lib/queryBuilder/StaticHookArguments.js +94 -106
- package/lib/queryBuilder/ValueBuilder.js +100 -112
- package/lib/queryBuilder/expressions.js +86 -116
- package/lib/queryBuilder/functions/mysql.js +642 -697
- package/lib/queryBuilder/graph/GraphAction.js +44 -59
- package/lib/queryBuilder/graph/GraphData.js +7 -9
- package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
- package/lib/queryBuilder/graph/GraphOperation.js +16 -22
- package/lib/queryBuilder/graph/GraphOptions.js +143 -185
- package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
- package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
- package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
- package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
- package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
- package/lib/queryBuilder/join/JoinResultParser.js +88 -101
- package/lib/queryBuilder/join/RelationJoiner.js +205 -288
- package/lib/queryBuilder/join/TableNode.js +117 -144
- package/lib/queryBuilder/join/TableTree.js +60 -76
- package/lib/queryBuilder/join/utils.js +10 -16
- package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
- package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
- package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
- package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
- package/lib/queryBuilder/operations/FindOperation.js +114 -131
- package/lib/queryBuilder/operations/FirstOperation.js +14 -19
- package/lib/queryBuilder/operations/FromOperation.js +69 -88
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
- package/lib/queryBuilder/operations/InsertOperation.js +132 -165
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
- package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
- package/lib/queryBuilder/operations/KnexOperation.js +4 -7
- package/lib/queryBuilder/operations/MergeOperation.js +32 -45
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
- package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
- package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
- package/lib/queryBuilder/operations/RangeOperation.js +30 -40
- package/lib/queryBuilder/operations/RelateOperation.js +14 -21
- package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
- package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
- package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
- package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
- package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
- package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
- package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
- package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
- package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
- package/lib/queryBuilder/operations/select/Selection.js +94 -105
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
- package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
- package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
- package/lib/queryBuilder/transformations/index.js +3 -9
- package/lib/queryBuilder/whereScopes.js +158 -186
- package/lib/relations/Relation.js +293 -375
- package/lib/relations/RelationDeleteOperation.js +24 -28
- package/lib/relations/RelationFindOperation.js +108 -138
- package/lib/relations/RelationInsertOperation.js +24 -32
- package/lib/relations/RelationOwner.js +175 -209
- package/lib/relations/RelationProperty.js +186 -223
- package/lib/relations/RelationUpdateOperation.js +23 -29
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +16 -21
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +30 -41
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +36 -47
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +42 -50
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +43 -58
- package/lib/relations/hasMany/HasManyInsertOperation.js +40 -56
- package/lib/relations/hasMany/HasManyRelateOperation.js +45 -61
- package/lib/relations/hasMany/HasManyRelation.js +38 -46
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +25 -32
- package/lib/relations/hasOne/HasOneRelation.js +9 -12
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +9 -12
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +73 -95
- package/lib/relations/manyToMany/ManyToManyRelation.js +374 -473
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +23 -30
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -10
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -25
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -12
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +77 -100
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +37 -49
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +58 -74
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +10 -13
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +26 -33
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +10 -15
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -10
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +61 -78
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -12
- package/lib/transaction.js +53 -83
- package/lib/utils/assert.js +15 -21
- package/lib/utils/buildUtils.js +17 -19
- package/lib/utils/classUtils.js +7 -11
- package/lib/utils/cloneDeep.js +365 -0
- package/lib/utils/createModifier.js +36 -41
- package/lib/utils/deprecate.js +8 -12
- package/lib/utils/identifierMapping.js +153 -192
- package/lib/utils/internalPropUtils.js +4 -8
- package/lib/utils/knexUtils.js +61 -56
- package/lib/utils/mixin.js +16 -23
- package/lib/utils/mysqlJsonPath.js +55 -40
- package/lib/utils/normalizeIds.js +110 -127
- package/lib/utils/objectUtils.js +236 -338
- package/lib/utils/parseFieldExpression.js +66 -44
- package/lib/utils/postgresJsonPath.js +48 -62
- package/lib/utils/promiseUtils/after.js +10 -13
- package/lib/utils/promiseUtils/afterReturn.js +10 -13
- package/lib/utils/promiseUtils/index.js +15 -17
- package/lib/utils/promiseUtils/isPromise.js +6 -9
- package/lib/utils/promiseUtils/map.js +75 -89
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
- package/lib/utils/promiseUtils/try.js +15 -18
- package/lib/utils/resolveModel.js +91 -94
- package/lib/utils/tmpColumnUtils.js +4 -13
- package/package.json +50 -23
- package/typings/objection/index.d.mts +362 -0
- package/typings/objection/index.d.ts +36 -9
- package/lib/.eslintrc.json +0 -8
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
- package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
- package/lib/utils/clone.js +0 -2329
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ref } = require('../ReferenceBuilder');
|
|
4
|
-
|
|
5
3
|
// The MySQL 8.4 built-in functions, as `fn.*` helpers.
|
|
6
4
|
//
|
|
7
5
|
// Each entry is `[name, sql, params, result, options]`:
|
|
@@ -32,7 +30,6 @@ const { ref } = require('../ReferenceBuilder');
|
|
|
32
30
|
// that are deprecated (`JSON_MERGE()`, `FOUND_ROWS()`, `VALUES()`,
|
|
33
31
|
// `MASTER_POS_WAIT()`) or that need a component (`VALIDATE_PASSWORD_STRENGTH()`).
|
|
34
32
|
// `fn('NAME', ...args)` calls any function.
|
|
35
|
-
|
|
36
33
|
const STR = 'string | null';
|
|
37
34
|
const NUM = 'number | null';
|
|
38
35
|
const DEC = 'FnNumeric | null';
|
|
@@ -41,777 +38,725 @@ const DATE = 'Date | string | null';
|
|
|
41
38
|
const TIME = 'string | null';
|
|
42
39
|
const BIN = 'Buffer | null';
|
|
43
40
|
const ANY = 'unknown';
|
|
44
|
-
|
|
45
41
|
const X = 'x: FnArg';
|
|
46
42
|
const STRING = 'str: FnArg';
|
|
47
43
|
const DATE_ARG = 'date: FnArg';
|
|
48
44
|
const FSP = 'fsp?: number';
|
|
49
45
|
const LAG_PARAMS = 'x: FnArg, offset?: number, defaultValue?: FnArg';
|
|
50
46
|
const WINDOW = { portable: true, window: true };
|
|
51
|
-
|
|
52
47
|
const INTERVAL_UNITS = [
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
48
|
+
'MICROSECOND',
|
|
49
|
+
'SECOND',
|
|
50
|
+
'MINUTE',
|
|
51
|
+
'HOUR',
|
|
52
|
+
'DAY',
|
|
53
|
+
'WEEK',
|
|
54
|
+
'MONTH',
|
|
55
|
+
'QUARTER',
|
|
56
|
+
'YEAR',
|
|
57
|
+
'SECOND_MICROSECOND',
|
|
58
|
+
'MINUTE_MICROSECOND',
|
|
59
|
+
'MINUTE_SECOND',
|
|
60
|
+
'HOUR_MICROSECOND',
|
|
61
|
+
'HOUR_SECOND',
|
|
62
|
+
'HOUR_MINUTE',
|
|
63
|
+
'DAY_MICROSECOND',
|
|
64
|
+
'DAY_SECOND',
|
|
65
|
+
'DAY_MINUTE',
|
|
66
|
+
'DAY_HOUR',
|
|
67
|
+
'YEAR_MONTH',
|
|
73
68
|
];
|
|
74
|
-
|
|
75
69
|
const TIMESTAMP_UNITS = INTERVAL_UNITS.slice(0, 9);
|
|
76
|
-
const CAST_TYPE =
|
|
77
|
-
/^((BINARY|CHAR|NCHAR)(\(\d+\))?( CHARACTER SET \w+)?|DATE|(DATETIME|TIME)(\(\d\))?|DECIMAL(\(\d+(, ?\d+)?\))?|DOUBLE|FLOAT(\(\d+\))?|JSON|REAL|(SIGNED|UNSIGNED)( INTEGER)?|YEAR)$/i;
|
|
70
|
+
const CAST_TYPE = /^((BINARY|CHAR|NCHAR)(\(\d+\))?( CHARACTER SET \w+)?|DATE|(DATETIME|TIME)(\(\d\))?|DECIMAL(\(\d+(, ?\d+)?\))?|DOUBLE|FLOAT(\(\d+\))?|JSON|REAL|(SIGNED|UNSIGNED)( INTEGER)?|YEAR)$/i;
|
|
78
71
|
const CHARSET = /^\w+$/;
|
|
79
72
|
const MATCH_MODES = {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
73
|
+
natural: 'IN NATURAL LANGUAGE MODE',
|
|
74
|
+
'natural with query expansion': 'IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION',
|
|
75
|
+
boolean: 'IN BOOLEAN MODE',
|
|
76
|
+
'with query expansion': 'WITH QUERY EXPANSION',
|
|
84
77
|
};
|
|
85
78
|
const TRIM_SIDES = ['BOTH', 'LEADING', 'TRAILING'];
|
|
86
79
|
const DIRECTIONS = ['ASC', 'DESC'];
|
|
87
80
|
const FORMAT_TYPES = ['DATE', 'TIME', 'DATETIME', 'TIMESTAMP'];
|
|
88
|
-
|
|
89
81
|
const FUNCTIONS = [
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
'
|
|
379
|
-
'
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
'
|
|
473
|
-
'
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
{ json: [0] },
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
'
|
|
532
|
-
|
|
533
|
-
'
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
'JSON_VALUE',
|
|
551
|
-
'doc: FnJsonArg, path: FnArg, options?: { returning?: string }',
|
|
552
|
-
ANY,
|
|
553
|
-
{ json: [0], build: buildJsonValue },
|
|
554
|
-
],
|
|
555
|
-
[
|
|
556
|
-
'memberOf',
|
|
557
|
-
'MEMBER OF',
|
|
558
|
-
'value: FnJsonArg, array: FnJsonArg',
|
|
559
|
-
BOOL,
|
|
560
|
-
{ json: [0, 1], build: buildMemberOf },
|
|
561
|
-
],
|
|
82
|
+
// String functions.
|
|
83
|
+
['ascii', 'ASCII', STRING, NUM, { portable: true }],
|
|
84
|
+
['bin', 'BIN', 'n: FnArg', STR],
|
|
85
|
+
['bitLength', 'BIT_LENGTH', STRING, NUM, { portable: true }],
|
|
86
|
+
[
|
|
87
|
+
'char',
|
|
88
|
+
'CHAR',
|
|
89
|
+
'codes: FnArg | FnArg[], options?: { using?: string }',
|
|
90
|
+
BIN,
|
|
91
|
+
{ build: buildChar },
|
|
92
|
+
],
|
|
93
|
+
['charLength', 'CHAR_LENGTH', STRING, NUM, { portable: true }],
|
|
94
|
+
['characterLength', 'CHARACTER_LENGTH', STRING, NUM, { portable: true }],
|
|
95
|
+
['concatWs', 'CONCAT_WS', 'separator: FnArg, ...strs: FnArg[]', STR, { portable: true }],
|
|
96
|
+
['elt', 'ELT', 'n: FnArg, ...strs: FnArg[]', STR],
|
|
97
|
+
[
|
|
98
|
+
'exportSet',
|
|
99
|
+
'EXPORT_SET',
|
|
100
|
+
'bits: FnArg, on: FnArg, off: FnArg, separator?: FnArg, numberOfBits?: FnArg',
|
|
101
|
+
STR,
|
|
102
|
+
],
|
|
103
|
+
['field', 'FIELD', 'str: FnArg, ...strs: FnArg[]', NUM],
|
|
104
|
+
['findInSet', 'FIND_IN_SET', 'str: FnArg, strList: FnArg', NUM],
|
|
105
|
+
['format', 'FORMAT', 'x: FnArg, decimals: FnArg, locale?: FnArg', STR],
|
|
106
|
+
['fromBase64', 'FROM_BASE64', STRING, BIN],
|
|
107
|
+
['hex', 'HEX', X, STR],
|
|
108
|
+
['insert', 'INSERT', 'str: FnArg, pos: FnArg, len: FnArg, newStr: FnArg', STR],
|
|
109
|
+
['instr', 'INSTR', 'str: FnArg, substr: FnArg', NUM],
|
|
110
|
+
['lcase', 'LCASE', STRING, STR],
|
|
111
|
+
['left', 'LEFT', 'str: FnArg, len: FnArg', STR, { portable: true }],
|
|
112
|
+
['length', 'LENGTH', STRING, NUM, { portable: true }],
|
|
113
|
+
['locate', 'LOCATE', 'substr: FnArg, str: FnArg, pos?: FnArg', NUM],
|
|
114
|
+
['lpad', 'LPAD', 'str: FnArg, len: FnArg, padStr: FnArg', STR, { portable: true }],
|
|
115
|
+
['ltrim', 'LTRIM', STRING, STR, { portable: true }],
|
|
116
|
+
['makeSet', 'MAKE_SET', 'bits: FnArg, ...strs: FnArg[]', STR],
|
|
117
|
+
['mid', 'MID', 'str: FnArg, pos: FnArg, len?: FnArg', STR],
|
|
118
|
+
['oct', 'OCT', 'n: FnArg', STR],
|
|
119
|
+
['octetLength', 'OCTET_LENGTH', STRING, NUM, { portable: true }],
|
|
120
|
+
['ord', 'ORD', STRING, NUM],
|
|
121
|
+
[
|
|
122
|
+
'position',
|
|
123
|
+
'POSITION',
|
|
124
|
+
'substr: FnArg, str: FnArg',
|
|
125
|
+
NUM,
|
|
126
|
+
{ portable: true, build: buildPosition },
|
|
127
|
+
],
|
|
128
|
+
['quote', 'QUOTE', STRING, STR],
|
|
129
|
+
[
|
|
130
|
+
'regexpInstr',
|
|
131
|
+
'REGEXP_INSTR',
|
|
132
|
+
'expr: FnArg, pattern: FnArg, pos?: FnArg, occurrence?: FnArg, returnOption?: FnArg, matchType?: FnArg',
|
|
133
|
+
NUM,
|
|
134
|
+
],
|
|
135
|
+
['regexpLike', 'REGEXP_LIKE', 'expr: FnArg, pattern: FnArg, matchType?: FnArg', BOOL],
|
|
136
|
+
[
|
|
137
|
+
'regexpReplace',
|
|
138
|
+
'REGEXP_REPLACE',
|
|
139
|
+
'expr: FnArg, pattern: FnArg, replacement: FnArg, pos?: FnArg, occurrence?: FnArg, matchType?: FnArg',
|
|
140
|
+
STR,
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
'regexpSubstr',
|
|
144
|
+
'REGEXP_SUBSTR',
|
|
145
|
+
'expr: FnArg, pattern: FnArg, pos?: FnArg, occurrence?: FnArg, matchType?: FnArg',
|
|
146
|
+
STR,
|
|
147
|
+
],
|
|
148
|
+
['repeat', 'REPEAT', 'str: FnArg, count: FnArg', STR, { portable: true }],
|
|
149
|
+
['replace', 'REPLACE', 'str: FnArg, from: FnArg, to: FnArg', STR, { portable: true }],
|
|
150
|
+
['reverse', 'REVERSE', STRING, STR, { portable: true }],
|
|
151
|
+
['right', 'RIGHT', 'str: FnArg, len: FnArg', STR, { portable: true }],
|
|
152
|
+
['rpad', 'RPAD', 'str: FnArg, len: FnArg, padStr: FnArg', STR, { portable: true }],
|
|
153
|
+
['rtrim', 'RTRIM', STRING, STR, { portable: true }],
|
|
154
|
+
['soundex', 'SOUNDEX', STRING, STR],
|
|
155
|
+
['space', 'SPACE', 'n: FnArg', STR],
|
|
156
|
+
['strcmp', 'STRCMP', 'a: FnArg, b: FnArg', '-1 | 0 | 1 | null'],
|
|
157
|
+
['substr', 'SUBSTR', 'str: FnArg, pos: FnArg, len?: FnArg', STR, { portable: true }],
|
|
158
|
+
['substring', 'SUBSTRING', 'str: FnArg, pos: FnArg, len?: FnArg', STR, { portable: true }],
|
|
159
|
+
['substringIndex', 'SUBSTRING_INDEX', 'str: FnArg, delimiter: FnArg, count: FnArg', STR],
|
|
160
|
+
['toBase64', 'TO_BASE64', STRING, STR],
|
|
161
|
+
[
|
|
162
|
+
'trim',
|
|
163
|
+
'TRIM',
|
|
164
|
+
"str: FnArg, options?: { side?: 'both' | 'leading' | 'trailing'; remove?: FnArg }",
|
|
165
|
+
STR,
|
|
166
|
+
{ portable: true, build: buildTrim },
|
|
167
|
+
],
|
|
168
|
+
['ucase', 'UCASE', STRING, STR],
|
|
169
|
+
['unhex', 'UNHEX', STRING, BIN],
|
|
170
|
+
['weightString', 'WEIGHT_STRING', STRING, BIN],
|
|
171
|
+
[
|
|
172
|
+
'match',
|
|
173
|
+
'MATCH',
|
|
174
|
+
"columns: FnArg | FnArg[], search: FnArg, options?: { mode?: 'natural' | 'natural with query expansion' | 'boolean' | 'with query expansion' }",
|
|
175
|
+
NUM,
|
|
176
|
+
{ build: buildMatch },
|
|
177
|
+
],
|
|
178
|
+
// Numeric functions.
|
|
179
|
+
['abs', 'ABS', X, DEC, { portable: true }],
|
|
180
|
+
['acos', 'ACOS', X, NUM, { portable: true }],
|
|
181
|
+
['asin', 'ASIN', X, NUM, { portable: true }],
|
|
182
|
+
['atan', 'ATAN', 'x: FnArg, y?: FnArg', NUM],
|
|
183
|
+
['atan2', 'ATAN2', 'y: FnArg, x: FnArg', NUM, { portable: true }],
|
|
184
|
+
['ceil', 'CEIL', X, DEC, { portable: true }],
|
|
185
|
+
['ceiling', 'CEILING', X, DEC, { portable: true }],
|
|
186
|
+
['conv', 'CONV', 'n: FnArg, fromBase: FnArg, toBase: FnArg', STR],
|
|
187
|
+
['cos', 'COS', X, NUM, { portable: true }],
|
|
188
|
+
['cot', 'COT', X, NUM, { portable: true }],
|
|
189
|
+
['crc32', 'CRC32', X, NUM],
|
|
190
|
+
['degrees', 'DEGREES', X, NUM, { portable: true }],
|
|
191
|
+
['exp', 'EXP', X, NUM, { portable: true }],
|
|
192
|
+
['floor', 'FLOOR', X, DEC, { portable: true }],
|
|
193
|
+
['ln', 'LN', X, NUM, { portable: true }],
|
|
194
|
+
['log', 'LOG', 'baseOrX: FnArg, x?: FnArg', NUM],
|
|
195
|
+
['log10', 'LOG10', X, NUM],
|
|
196
|
+
['log2', 'LOG2', X, NUM],
|
|
197
|
+
['mod', 'MOD', 'n: FnArg, m: FnArg', DEC, { portable: true }],
|
|
198
|
+
['pi', 'PI', '', NUM, { portable: true }],
|
|
199
|
+
['pow', 'POW', 'x: FnArg, y: FnArg', NUM],
|
|
200
|
+
['power', 'POWER', 'x: FnArg, y: FnArg', NUM, { portable: true }],
|
|
201
|
+
['radians', 'RADIANS', X, NUM, { portable: true }],
|
|
202
|
+
['rand', 'RAND', 'seed?: FnArg', NUM],
|
|
203
|
+
['round', 'ROUND', 'x: FnArg, decimals?: FnArg', DEC, { portable: true }],
|
|
204
|
+
['sign', 'SIGN', X, NUM, { portable: true }],
|
|
205
|
+
['sin', 'SIN', X, NUM, { portable: true }],
|
|
206
|
+
['sqrt', 'SQRT', X, NUM, { portable: true }],
|
|
207
|
+
['tan', 'TAN', X, NUM, { portable: true }],
|
|
208
|
+
['truncate', 'TRUNCATE', 'x: FnArg, decimals: FnArg', DEC],
|
|
209
|
+
// Date and time functions.
|
|
210
|
+
[
|
|
211
|
+
'addDate',
|
|
212
|
+
'ADDDATE',
|
|
213
|
+
'date: FnArg, amount: FnArg, unit?: FnIntervalUnit',
|
|
214
|
+
DATE,
|
|
215
|
+
{ build: buildDateAdd },
|
|
216
|
+
],
|
|
217
|
+
['addTime', 'ADDTIME', 'datetime: FnArg, time: FnArg', DATE],
|
|
218
|
+
['convertTz', 'CONVERT_TZ', 'datetime: FnArg, fromTz: FnArg, toTz: FnArg', DATE],
|
|
219
|
+
['curDate', 'CURDATE', '', DATE],
|
|
220
|
+
['currentDate', 'CURRENT_DATE', '', DATE],
|
|
221
|
+
['currentTime', 'CURRENT_TIME', FSP, TIME],
|
|
222
|
+
['currentTimestamp', 'CURRENT_TIMESTAMP', FSP, DATE],
|
|
223
|
+
['curTime', 'CURTIME', FSP, TIME],
|
|
224
|
+
['date', 'DATE', X, DATE],
|
|
225
|
+
[
|
|
226
|
+
'dateAdd',
|
|
227
|
+
'DATE_ADD',
|
|
228
|
+
'date: FnArg, amount: FnArg, unit: FnIntervalUnit',
|
|
229
|
+
DATE,
|
|
230
|
+
{ build: buildDateAdd },
|
|
231
|
+
],
|
|
232
|
+
['dateDiff', 'DATEDIFF', 'a: FnArg, b: FnArg', NUM],
|
|
233
|
+
['dateFormat', 'DATE_FORMAT', 'date: FnArg, format: FnArg', STR],
|
|
234
|
+
[
|
|
235
|
+
'dateSub',
|
|
236
|
+
'DATE_SUB',
|
|
237
|
+
'date: FnArg, amount: FnArg, unit: FnIntervalUnit',
|
|
238
|
+
DATE,
|
|
239
|
+
{ build: buildDateAdd },
|
|
240
|
+
],
|
|
241
|
+
['day', 'DAY', DATE_ARG, NUM],
|
|
242
|
+
['dayName', 'DAYNAME', DATE_ARG, STR],
|
|
243
|
+
['dayOfMonth', 'DAYOFMONTH', DATE_ARG, NUM],
|
|
244
|
+
['dayOfWeek', 'DAYOFWEEK', DATE_ARG, NUM],
|
|
245
|
+
['dayOfYear', 'DAYOFYEAR', DATE_ARG, NUM],
|
|
246
|
+
['extract', 'EXTRACT', 'unit: FnIntervalUnit, date: FnArg', NUM, { build: buildExtract }],
|
|
247
|
+
['fromDays', 'FROM_DAYS', 'days: FnArg', DATE],
|
|
248
|
+
['fromUnixTime', 'FROM_UNIXTIME', 'timestamp: FnArg, format?: FnArg', DATE],
|
|
249
|
+
[
|
|
250
|
+
'getFormat',
|
|
251
|
+
'GET_FORMAT',
|
|
252
|
+
"type: 'DATE' | 'TIME' | 'DATETIME' | 'TIMESTAMP', locale: FnArg",
|
|
253
|
+
STR,
|
|
254
|
+
{ build: buildGetFormat },
|
|
255
|
+
],
|
|
256
|
+
['hour', 'HOUR', 'time: FnArg', NUM],
|
|
257
|
+
['lastDay', 'LAST_DAY', DATE_ARG, DATE],
|
|
258
|
+
['localTime', 'LOCALTIME', FSP, DATE],
|
|
259
|
+
['localTimestamp', 'LOCALTIMESTAMP', FSP, DATE],
|
|
260
|
+
['makeDate', 'MAKEDATE', 'year: FnArg, dayOfYear: FnArg', DATE],
|
|
261
|
+
['makeTime', 'MAKETIME', 'hour: FnArg, minute: FnArg, second: FnArg', TIME],
|
|
262
|
+
['microsecond', 'MICROSECOND', 'time: FnArg', NUM],
|
|
263
|
+
['minute', 'MINUTE', 'time: FnArg', NUM],
|
|
264
|
+
['month', 'MONTH', DATE_ARG, NUM],
|
|
265
|
+
['monthName', 'MONTHNAME', DATE_ARG, STR],
|
|
266
|
+
['periodAdd', 'PERIOD_ADD', 'period: FnArg, months: FnArg', NUM],
|
|
267
|
+
['periodDiff', 'PERIOD_DIFF', 'a: FnArg, b: FnArg', NUM],
|
|
268
|
+
['quarter', 'QUARTER', DATE_ARG, NUM],
|
|
269
|
+
['second', 'SECOND', 'time: FnArg', NUM],
|
|
270
|
+
['secToTime', 'SEC_TO_TIME', 'seconds: FnArg', TIME],
|
|
271
|
+
['strToDate', 'STR_TO_DATE', 'str: FnArg, format: FnArg', DATE],
|
|
272
|
+
[
|
|
273
|
+
'subDate',
|
|
274
|
+
'SUBDATE',
|
|
275
|
+
'date: FnArg, amount: FnArg, unit?: FnIntervalUnit',
|
|
276
|
+
DATE,
|
|
277
|
+
{ build: buildDateAdd },
|
|
278
|
+
],
|
|
279
|
+
['subTime', 'SUBTIME', 'datetime: FnArg, time: FnArg', DATE],
|
|
280
|
+
['sysdate', 'SYSDATE', FSP, DATE],
|
|
281
|
+
['time', 'TIME', X, TIME],
|
|
282
|
+
['timeDiff', 'TIMEDIFF', 'a: FnArg, b: FnArg', TIME],
|
|
283
|
+
['timestamp', 'TIMESTAMP', 'x: FnArg, time?: FnArg', DATE],
|
|
284
|
+
[
|
|
285
|
+
'timestampAdd',
|
|
286
|
+
'TIMESTAMPADD',
|
|
287
|
+
'unit: FnTimestampUnit, amount: FnArg, date: FnArg',
|
|
288
|
+
DATE,
|
|
289
|
+
{ build: buildTimestampFunction },
|
|
290
|
+
],
|
|
291
|
+
[
|
|
292
|
+
'timestampDiff',
|
|
293
|
+
'TIMESTAMPDIFF',
|
|
294
|
+
'unit: FnTimestampUnit, from: FnArg, to: FnArg',
|
|
295
|
+
NUM,
|
|
296
|
+
{ build: buildTimestampFunction },
|
|
297
|
+
],
|
|
298
|
+
['timeFormat', 'TIME_FORMAT', 'time: FnArg, format: FnArg', STR],
|
|
299
|
+
['timeToSec', 'TIME_TO_SEC', 'time: FnArg', NUM],
|
|
300
|
+
['toDays', 'TO_DAYS', DATE_ARG, NUM],
|
|
301
|
+
['toSeconds', 'TO_SECONDS', DATE_ARG, NUM],
|
|
302
|
+
['unixTimestamp', 'UNIX_TIMESTAMP', 'date?: FnArg', DEC],
|
|
303
|
+
['utcDate', 'UTC_DATE', '', DATE],
|
|
304
|
+
['utcTime', 'UTC_TIME', FSP, TIME],
|
|
305
|
+
['utcTimestamp', 'UTC_TIMESTAMP', FSP, DATE],
|
|
306
|
+
['week', 'WEEK', 'date: FnArg, mode?: FnArg', NUM],
|
|
307
|
+
['weekday', 'WEEKDAY', DATE_ARG, NUM],
|
|
308
|
+
['weekOfYear', 'WEEKOFYEAR', DATE_ARG, NUM],
|
|
309
|
+
['year', 'YEAR', DATE_ARG, NUM],
|
|
310
|
+
['yearWeek', 'YEARWEEK', 'date: FnArg, mode?: FnArg', NUM],
|
|
311
|
+
// Aggregate functions. `fn.count()`, `fn.sum()`, `fn.avg()`, `fn.min()` and
|
|
312
|
+
// `fn.max()` already exist.
|
|
313
|
+
['bitAnd', 'BIT_AND', X, DEC, { aggregate: true }],
|
|
314
|
+
['bitOr', 'BIT_OR', X, DEC, { aggregate: true }],
|
|
315
|
+
['bitXor', 'BIT_XOR', X, DEC, { aggregate: true }],
|
|
316
|
+
[
|
|
317
|
+
'countDistinct',
|
|
318
|
+
'COUNT',
|
|
319
|
+
'...exprs: FnArg[]',
|
|
320
|
+
'number',
|
|
321
|
+
{ build: buildCountDistinct, aggregate: true, portable: true },
|
|
322
|
+
],
|
|
323
|
+
[
|
|
324
|
+
'groupConcat',
|
|
325
|
+
'GROUP_CONCAT',
|
|
326
|
+
'exprs: FnArg | FnArg[], options?: { distinct?: boolean; orderBy?: FnOrderBy | FnOrderBy[]; separator?: string }',
|
|
327
|
+
STR,
|
|
328
|
+
{ build: buildGroupConcat, aggregate: ([exprs]) => (Array.isArray(exprs) ? exprs.length : 1) },
|
|
329
|
+
],
|
|
330
|
+
['jsonArrayAgg', 'JSON_ARRAYAGG', X, 'unknown[] | null', { aggregate: true }],
|
|
331
|
+
['jsonObjectAgg', 'JSON_OBJECTAGG', 'key: FnArg, value: FnArg', 'Record<string, unknown> | null'],
|
|
332
|
+
['std', 'STD', X, NUM, { aggregate: true }],
|
|
333
|
+
['stddev', 'STDDEV', X, NUM, { portable: true, aggregate: true }],
|
|
334
|
+
['stddevPop', 'STDDEV_POP', X, NUM, { portable: true, aggregate: true }],
|
|
335
|
+
['stddevSamp', 'STDDEV_SAMP', X, NUM, { portable: true, aggregate: true }],
|
|
336
|
+
['variance', 'VARIANCE', X, NUM, { portable: true, aggregate: true }],
|
|
337
|
+
['varPop', 'VAR_POP', X, NUM, { portable: true, aggregate: true }],
|
|
338
|
+
['varSamp', 'VAR_SAMP', X, NUM, { portable: true, aggregate: true }],
|
|
339
|
+
// Window functions. They need `over()`: `fn.rowNumber().over({ orderBy })`.
|
|
340
|
+
// Aggregate functions work as window functions too.
|
|
341
|
+
['rowNumber', 'ROW_NUMBER', '', 'number', WINDOW],
|
|
342
|
+
['rank', 'RANK', '', 'number', WINDOW],
|
|
343
|
+
['denseRank', 'DENSE_RANK', '', 'number', WINDOW],
|
|
344
|
+
['percentRank', 'PERCENT_RANK', '', 'number', WINDOW],
|
|
345
|
+
['cumeDist', 'CUME_DIST', '', 'number', WINDOW],
|
|
346
|
+
['ntile', 'NTILE', 'buckets: number', 'number', { ...WINDOW, build: buildNtile }],
|
|
347
|
+
['lag', 'LAG', LAG_PARAMS, ANY, { ...WINDOW, build: buildLagOrLead }],
|
|
348
|
+
['lead', 'LEAD', LAG_PARAMS, ANY, { ...WINDOW, build: buildLagOrLead }],
|
|
349
|
+
['firstValue', 'FIRST_VALUE', X, ANY, WINDOW],
|
|
350
|
+
['lastValue', 'LAST_VALUE', X, ANY, WINDOW],
|
|
351
|
+
['nthValue', 'NTH_VALUE', 'x: FnArg, n: number', ANY, { ...WINDOW, build: buildNthValue }],
|
|
352
|
+
// Comparison and flow control functions. `fn.coalesce()` already exists.
|
|
353
|
+
['greatest', 'GREATEST', '...values: FnArg[]', ANY, { portable: true }],
|
|
354
|
+
['if', 'IF', 'condition: FnArg, then: FnArg, otherwise: FnArg', ANY],
|
|
355
|
+
['ifNull', 'IFNULL', 'value: FnArg, otherwise: FnArg', ANY],
|
|
356
|
+
['interval', 'INTERVAL', 'n: FnArg, ...ns: FnArg[]', NUM],
|
|
357
|
+
['isNull', 'ISNULL', X, BOOL],
|
|
358
|
+
['least', 'LEAST', '...values: FnArg[]', ANY, { portable: true }],
|
|
359
|
+
['nullIf', 'NULLIF', 'a: FnArg, b: FnArg', ANY, { portable: true }],
|
|
360
|
+
// Cast functions.
|
|
361
|
+
['cast', 'CAST', 'x: FnArg, type: string', ANY, { build: buildCast }],
|
|
362
|
+
[
|
|
363
|
+
'convert',
|
|
364
|
+
'CONVERT',
|
|
365
|
+
'x: FnArg, type: string | { using: string }',
|
|
366
|
+
ANY,
|
|
367
|
+
{ build: buildConvert },
|
|
368
|
+
],
|
|
369
|
+
// Information functions.
|
|
370
|
+
['charset', 'CHARSET', STRING, STR],
|
|
371
|
+
['coercibility', 'COERCIBILITY', STRING, NUM],
|
|
372
|
+
['collation', 'COLLATION', STRING, STR],
|
|
373
|
+
['connectionId', 'CONNECTION_ID', '', NUM],
|
|
374
|
+
['currentRole', 'CURRENT_ROLE', '', STR],
|
|
375
|
+
['currentUser', 'CURRENT_USER', '', STR],
|
|
376
|
+
['database', 'DATABASE', '', STR],
|
|
377
|
+
['icuVersion', 'ICU_VERSION', '', STR],
|
|
378
|
+
['lastInsertId', 'LAST_INSERT_ID', 'x?: FnArg', NUM],
|
|
379
|
+
['rolesGraphml', 'ROLES_GRAPHML', '', STR],
|
|
380
|
+
['rowCount', 'ROW_COUNT', '', NUM],
|
|
381
|
+
['schema', 'SCHEMA', '', STR],
|
|
382
|
+
['sessionUser', 'SESSION_USER', '', STR],
|
|
383
|
+
['systemUser', 'SYSTEM_USER', '', STR],
|
|
384
|
+
['user', 'USER', '', STR],
|
|
385
|
+
['version', 'VERSION', '', STR],
|
|
386
|
+
// Encryption and compression functions.
|
|
387
|
+
['aesDecrypt', 'AES_DECRYPT', 'crypt: FnArg, key: FnArg, ...options: FnArg[]', BIN],
|
|
388
|
+
['aesEncrypt', 'AES_ENCRYPT', 'str: FnArg, key: FnArg, ...options: FnArg[]', BIN],
|
|
389
|
+
['compress', 'COMPRESS', STRING, BIN],
|
|
390
|
+
['md5', 'MD5', STRING, STR, { portable: true }],
|
|
391
|
+
['randomBytes', 'RANDOM_BYTES', 'length: FnArg', BIN],
|
|
392
|
+
['sha1', 'SHA1', STRING, STR],
|
|
393
|
+
['sha2', 'SHA2', 'str: FnArg, hashLength: FnArg', STR],
|
|
394
|
+
['statementDigest', 'STATEMENT_DIGEST', 'statement: FnArg', STR],
|
|
395
|
+
['statementDigestText', 'STATEMENT_DIGEST_TEXT', 'statement: FnArg', STR],
|
|
396
|
+
['uncompress', 'UNCOMPRESS', STRING, BIN],
|
|
397
|
+
['uncompressedLength', 'UNCOMPRESSED_LENGTH', STRING, NUM],
|
|
398
|
+
// Locking functions.
|
|
399
|
+
['getLock', 'GET_LOCK', 'name: FnArg, timeout: FnArg', BOOL],
|
|
400
|
+
['isFreeLock', 'IS_FREE_LOCK', 'name: FnArg', BOOL],
|
|
401
|
+
['isUsedLock', 'IS_USED_LOCK', 'name: FnArg', NUM],
|
|
402
|
+
['releaseAllLocks', 'RELEASE_ALL_LOCKS', '', NUM],
|
|
403
|
+
['releaseLock', 'RELEASE_LOCK', 'name: FnArg', BOOL],
|
|
404
|
+
// Miscellaneous functions.
|
|
405
|
+
['anyValue', 'ANY_VALUE', X, ANY],
|
|
406
|
+
['binToUuid', 'BIN_TO_UUID', 'bin: FnArg, swap?: FnArg', STR],
|
|
407
|
+
['default', 'DEFAULT', 'column: FnArg', ANY],
|
|
408
|
+
['grouping', 'GROUPING', '...exprs: FnArg[]', NUM],
|
|
409
|
+
['inet6Aton', 'INET6_ATON', 'address: FnArg', BIN],
|
|
410
|
+
['inet6Ntoa', 'INET6_NTOA', 'address: FnArg', STR],
|
|
411
|
+
['inetAton', 'INET_ATON', 'address: FnArg', NUM],
|
|
412
|
+
['inetNtoa', 'INET_NTOA', 'address: FnArg', STR],
|
|
413
|
+
['isIpv4', 'IS_IPV4', 'address: FnArg', BOOL],
|
|
414
|
+
['isIpv4Compat', 'IS_IPV4_COMPAT', 'address: FnArg', BOOL],
|
|
415
|
+
['isIpv4Mapped', 'IS_IPV4_MAPPED', 'address: FnArg', BOOL],
|
|
416
|
+
['isIpv6', 'IS_IPV6', 'address: FnArg', BOOL],
|
|
417
|
+
['isUuid', 'IS_UUID', 'uuid: FnArg', BOOL],
|
|
418
|
+
['sleep', 'SLEEP', 'seconds: FnArg', NUM],
|
|
419
|
+
['uuid', 'UUID', '', 'string'],
|
|
420
|
+
['uuidShort', 'UUID_SHORT', '', 'FnNumeric'],
|
|
421
|
+
['uuidToBin', 'UUID_TO_BIN', 'uuid: FnArg, swap?: FnArg', BIN],
|
|
422
|
+
// Bit, performance schema, GTID and XML functions.
|
|
423
|
+
['bitCount', 'BIT_COUNT', X, NUM],
|
|
424
|
+
['formatBytes', 'FORMAT_BYTES', 'bytes: FnArg', STR],
|
|
425
|
+
['formatPicoTime', 'FORMAT_PICO_TIME', 'time: FnArg', STR],
|
|
426
|
+
['psCurrentThreadId', 'PS_CURRENT_THREAD_ID', '', NUM],
|
|
427
|
+
['psThreadId', 'PS_THREAD_ID', 'connectionId: FnArg', NUM],
|
|
428
|
+
['gtidSubset', 'GTID_SUBSET', 'set1: FnArg, set2: FnArg', BOOL],
|
|
429
|
+
['gtidSubtract', 'GTID_SUBTRACT', 'set1: FnArg, set2: FnArg', STR],
|
|
430
|
+
['sourcePosWait', 'SOURCE_POS_WAIT', 'logName: FnArg, logPos: FnArg, ...options: FnArg[]', NUM],
|
|
431
|
+
['waitForExecutedGtidSet', 'WAIT_FOR_EXECUTED_GTID_SET', 'gtidSet: FnArg, timeout?: FnArg', NUM],
|
|
432
|
+
['extractValue', 'EXTRACTVALUE', 'xml: FnArg, xpath: FnArg', STR],
|
|
433
|
+
['updateXml', 'UPDATEXML', 'xml: FnArg, xpath: FnArg, newXml: FnArg', STR],
|
|
434
|
+
// JSON functions. Objects and arrays passed as JSON documents are cast to JSON.
|
|
435
|
+
['jsonArray', 'JSON_ARRAY', '...values: FnJsonArg[]', 'unknown[]', { json: 'all' }],
|
|
436
|
+
[
|
|
437
|
+
'jsonArrayAppend',
|
|
438
|
+
'JSON_ARRAY_APPEND',
|
|
439
|
+
'doc: FnJsonArg, path: FnArg, value: FnJsonArg, ...pathsAndValues: FnJsonArg[]',
|
|
440
|
+
ANY,
|
|
441
|
+
{ json: 'even' },
|
|
442
|
+
],
|
|
443
|
+
[
|
|
444
|
+
'jsonArrayInsert',
|
|
445
|
+
'JSON_ARRAY_INSERT',
|
|
446
|
+
'doc: FnJsonArg, path: FnArg, value: FnJsonArg, ...pathsAndValues: FnJsonArg[]',
|
|
447
|
+
ANY,
|
|
448
|
+
{ json: 'even' },
|
|
449
|
+
],
|
|
450
|
+
[
|
|
451
|
+
'jsonContains',
|
|
452
|
+
'JSON_CONTAINS',
|
|
453
|
+
'target: FnJsonArg, candidate: FnJsonArg, path?: FnArg',
|
|
454
|
+
BOOL,
|
|
455
|
+
{ json: [0, 1] },
|
|
456
|
+
],
|
|
457
|
+
[
|
|
458
|
+
'jsonContainsPath',
|
|
459
|
+
'JSON_CONTAINS_PATH',
|
|
460
|
+
"doc: FnJsonArg, oneOrAll: 'one' | 'all', ...paths: FnArg[]",
|
|
461
|
+
BOOL,
|
|
462
|
+
{ json: [0] },
|
|
463
|
+
],
|
|
464
|
+
['jsonDepth', 'JSON_DEPTH', 'doc: FnJsonArg', NUM, { json: [0] }],
|
|
465
|
+
['jsonExtract', 'JSON_EXTRACT', 'doc: FnJsonArg, ...paths: FnArg[]', ANY, { json: [0] }],
|
|
466
|
+
[
|
|
467
|
+
'jsonInsert',
|
|
468
|
+
'JSON_INSERT',
|
|
469
|
+
'doc: FnJsonArg, path: FnArg, value: FnJsonArg, ...pathsAndValues: FnJsonArg[]',
|
|
470
|
+
ANY,
|
|
471
|
+
{ json: 'even' },
|
|
472
|
+
],
|
|
473
|
+
['jsonKeys', 'JSON_KEYS', 'doc: FnJsonArg, path?: FnArg', 'string[] | null', { json: [0] }],
|
|
474
|
+
['jsonLength', 'JSON_LENGTH', 'doc: FnJsonArg, path?: FnArg', NUM, { json: [0] }],
|
|
475
|
+
['jsonMergePatch', 'JSON_MERGE_PATCH', '...docs: FnJsonArg[]', ANY, { json: 'all' }],
|
|
476
|
+
['jsonMergePreserve', 'JSON_MERGE_PRESERVE', '...docs: FnJsonArg[]', ANY, { json: 'all' }],
|
|
477
|
+
[
|
|
478
|
+
'jsonObject',
|
|
479
|
+
'JSON_OBJECT',
|
|
480
|
+
'objectOrKeysAndValues?: { [key: string]: FnJsonArg } | FnJsonArg, ...keysAndValues: FnJsonArg[]',
|
|
481
|
+
'Record<string, unknown>',
|
|
482
|
+
{ json: 'odd', build: buildJsonObject },
|
|
483
|
+
],
|
|
484
|
+
['jsonOverlaps', 'JSON_OVERLAPS', 'a: FnJsonArg, b: FnJsonArg', BOOL, { json: [0, 1] }],
|
|
485
|
+
['jsonPretty', 'JSON_PRETTY', 'doc: FnJsonArg', STR, { json: [0] }],
|
|
486
|
+
['jsonQuote', 'JSON_QUOTE', STRING, STR],
|
|
487
|
+
['jsonRemove', 'JSON_REMOVE', 'doc: FnJsonArg, ...paths: FnArg[]', ANY, { json: [0] }],
|
|
488
|
+
[
|
|
489
|
+
'jsonReplace',
|
|
490
|
+
'JSON_REPLACE',
|
|
491
|
+
'doc: FnJsonArg, path: FnArg, value: FnJsonArg, ...pathsAndValues: FnJsonArg[]',
|
|
492
|
+
ANY,
|
|
493
|
+
{ json: 'even' },
|
|
494
|
+
],
|
|
495
|
+
[
|
|
496
|
+
'jsonSchemaValid',
|
|
497
|
+
'JSON_SCHEMA_VALID',
|
|
498
|
+
'schema: FnJsonArg, doc: FnJsonArg',
|
|
499
|
+
BOOL,
|
|
500
|
+
{ json: [0, 1] },
|
|
501
|
+
],
|
|
502
|
+
[
|
|
503
|
+
'jsonSchemaValidationReport',
|
|
504
|
+
'JSON_SCHEMA_VALIDATION_REPORT',
|
|
505
|
+
'schema: FnJsonArg, doc: FnJsonArg',
|
|
506
|
+
'Record<string, unknown> | null',
|
|
507
|
+
{ json: [0, 1] },
|
|
508
|
+
],
|
|
509
|
+
[
|
|
510
|
+
'jsonSearch',
|
|
511
|
+
'JSON_SEARCH',
|
|
512
|
+
"doc: FnJsonArg, oneOrAll: 'one' | 'all', search: FnArg, escape?: FnArg, ...paths: FnArg[]",
|
|
513
|
+
'string | string[] | null',
|
|
514
|
+
{ json: [0] },
|
|
515
|
+
],
|
|
516
|
+
[
|
|
517
|
+
'jsonSet',
|
|
518
|
+
'JSON_SET',
|
|
519
|
+
'doc: FnJsonArg, path: FnArg, value: FnJsonArg, ...pathsAndValues: FnJsonArg[]',
|
|
520
|
+
ANY,
|
|
521
|
+
{ json: 'even' },
|
|
522
|
+
],
|
|
523
|
+
['jsonStorageFree', 'JSON_STORAGE_FREE', 'doc: FnJsonArg', NUM, { json: [0] }],
|
|
524
|
+
['jsonStorageSize', 'JSON_STORAGE_SIZE', 'doc: FnJsonArg', NUM, { json: [0] }],
|
|
525
|
+
['jsonType', 'JSON_TYPE', 'value: FnJsonArg', STR, { json: [0] }],
|
|
526
|
+
['jsonUnquote', 'JSON_UNQUOTE', STRING, STR],
|
|
527
|
+
['jsonValid', 'JSON_VALID', 'value: FnArg', BOOL],
|
|
528
|
+
[
|
|
529
|
+
'jsonValue',
|
|
530
|
+
'JSON_VALUE',
|
|
531
|
+
'doc: FnJsonArg, path: FnArg, options?: { returning?: string }',
|
|
532
|
+
ANY,
|
|
533
|
+
{ json: [0], build: buildJsonValue },
|
|
534
|
+
],
|
|
535
|
+
[
|
|
536
|
+
'memberOf',
|
|
537
|
+
'MEMBER OF',
|
|
538
|
+
'value: FnJsonArg, array: FnJsonArg',
|
|
539
|
+
BOOL,
|
|
540
|
+
{ json: [0, 1], build: buildMemberOf },
|
|
541
|
+
],
|
|
562
542
|
];
|
|
563
|
-
|
|
564
543
|
// Builders for the functions with keywords in their syntax. They return
|
|
565
544
|
// `[sql, args]`. Keywords are checked against lists, since they can't be bindings.
|
|
566
|
-
|
|
567
545
|
function buildDateAdd(name, sql, [date, amount, unit]) {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
return [`${sql}(?, INTERVAL ? ${keyword(name, 'unit', unit, INTERVAL_UNITS)})`, [date, amount]];
|
|
546
|
+
if (unit === undefined && (sql === 'ADDDATE' || sql === 'SUBDATE')) {
|
|
547
|
+
// The `ADDDATE(date, days)` form.
|
|
548
|
+
return [`${sql}(?, ?)`, [date, amount]];
|
|
549
|
+
}
|
|
550
|
+
return [`${sql}(?, INTERVAL ? ${keyword(name, 'unit', unit, INTERVAL_UNITS)})`, [date, amount]];
|
|
574
551
|
}
|
|
575
|
-
|
|
576
552
|
function buildTimestampFunction(name, sql, [unit, a, b]) {
|
|
577
|
-
|
|
553
|
+
return [`${sql}(${keyword(name, 'unit', unit, TIMESTAMP_UNITS)}, ?, ?)`, [a, b]];
|
|
578
554
|
}
|
|
579
|
-
|
|
580
555
|
function buildExtract(name, sql, [unit, date]) {
|
|
581
|
-
|
|
556
|
+
return [`EXTRACT(${keyword(name, 'unit', unit, INTERVAL_UNITS)} FROM ?)`, [date]];
|
|
582
557
|
}
|
|
583
|
-
|
|
584
558
|
function buildGetFormat(name, sql, [type, locale]) {
|
|
585
|
-
|
|
559
|
+
return [`GET_FORMAT(${keyword(name, 'type', type, FORMAT_TYPES)}, ?)`, [locale]];
|
|
586
560
|
}
|
|
587
|
-
|
|
588
561
|
function buildCast(name, sql, [value, type]) {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
return [`CAST(? AS ${type.trim().toUpperCase()})`, [value]];
|
|
562
|
+
if (typeof type !== 'string' || !CAST_TYPE.test(type.trim())) {
|
|
563
|
+
throw new Error(`fn.cast(): invalid type ${JSON.stringify(type)}`);
|
|
564
|
+
}
|
|
565
|
+
return [`CAST(? AS ${type.trim().toUpperCase()})`, [value]];
|
|
594
566
|
}
|
|
595
|
-
|
|
596
567
|
function buildConvert(name, sql, [value, type]) {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
568
|
+
if (type !== null && typeof type === 'object') {
|
|
569
|
+
if (typeof type.using !== 'string' || !CHARSET.test(type.using)) {
|
|
570
|
+
throw new Error(`fn.convert(): invalid character set ${JSON.stringify(type.using)}`);
|
|
571
|
+
}
|
|
572
|
+
return [`CONVERT(? USING ${type.using})`, [value]];
|
|
573
|
+
}
|
|
574
|
+
if (typeof type !== 'string' || !CAST_TYPE.test(type.trim())) {
|
|
575
|
+
throw new Error(`fn.convert(): invalid type ${JSON.stringify(type)}`);
|
|
600
576
|
}
|
|
601
|
-
|
|
602
|
-
return [`CONVERT(? USING ${type.using})`, [value]];
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (typeof type !== 'string' || !CAST_TYPE.test(type.trim())) {
|
|
606
|
-
throw new Error(`fn.convert(): invalid type ${JSON.stringify(type)}`);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
return [`CONVERT(?, ${type.trim().toUpperCase()})`, [value]];
|
|
577
|
+
return [`CONVERT(?, ${type.trim().toUpperCase()})`, [value]];
|
|
610
578
|
}
|
|
611
|
-
|
|
612
579
|
function buildPosition(name, sql, [substr, str]) {
|
|
613
|
-
|
|
580
|
+
return ['POSITION(? IN ?)', [substr, str]];
|
|
614
581
|
}
|
|
615
|
-
|
|
616
582
|
function buildTrim(name, sql, [str, options = {}]) {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
return [`TRIM(${side} ? FROM ?)`, [options.remove, str]];
|
|
628
|
-
}
|
|
583
|
+
if (options.side === undefined && options.remove === undefined) {
|
|
584
|
+
return ['TRIM(?)', [str]];
|
|
585
|
+
}
|
|
586
|
+
const side = options.side === undefined ? 'BOTH' : keyword(name, 'side', options.side, TRIM_SIDES);
|
|
587
|
+
if (options.remove === undefined) {
|
|
588
|
+
return [`TRIM(${side} FROM ?)`, [str]];
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
return [`TRIM(${side} ? FROM ?)`, [options.remove, str]];
|
|
592
|
+
}
|
|
629
593
|
}
|
|
630
|
-
|
|
631
594
|
function buildChar(name, sql, [codes, options = {}]) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
return [`CHAR(${placeholders} USING ${options.using})`, codes];
|
|
595
|
+
codes = Array.isArray(codes) ? codes : [codes];
|
|
596
|
+
const placeholders = codes.map(() => '?').join(', ');
|
|
597
|
+
if (options.using === undefined) {
|
|
598
|
+
return [`CHAR(${placeholders})`, codes];
|
|
599
|
+
}
|
|
600
|
+
if (typeof options.using !== 'string' || !CHARSET.test(options.using)) {
|
|
601
|
+
throw new Error(`fn.char(): invalid character set ${JSON.stringify(options.using)}`);
|
|
602
|
+
}
|
|
603
|
+
return [`CHAR(${placeholders} USING ${options.using})`, codes];
|
|
644
604
|
}
|
|
645
|
-
|
|
646
605
|
function buildMatch(name, sql, [columns, search, options = {}]) {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
606
|
+
columns = Array.isArray(columns) ? columns : [columns];
|
|
607
|
+
let mode = '';
|
|
608
|
+
if (options.mode !== undefined) {
|
|
609
|
+
mode = MATCH_MODES[options.mode];
|
|
610
|
+
if (!mode) {
|
|
611
|
+
throw new Error(`fn.match(): invalid mode ${JSON.stringify(options.mode)}`);
|
|
612
|
+
}
|
|
613
|
+
mode = ` ${mode}`;
|
|
655
614
|
}
|
|
656
|
-
|
|
657
|
-
mode = ` ${mode}`;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
return [`MATCH(${columns.map(() => '?').join(', ')}) AGAINST(?${mode})`, [...columns, search]];
|
|
615
|
+
return [`MATCH(${columns.map(() => '?').join(', ')}) AGAINST(?${mode})`, [...columns, search]];
|
|
661
616
|
}
|
|
662
|
-
|
|
663
617
|
function buildCountDistinct(name, sql, exprs) {
|
|
664
|
-
|
|
618
|
+
return [`COUNT(DISTINCT ${exprs.map(() => '?').join(', ')})`, exprs];
|
|
665
619
|
}
|
|
666
|
-
|
|
667
620
|
function buildGroupConcat(name, sql, [exprs, options = {}]) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
text
|
|
681
|
-
args.push(options.separator);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
return [`${text})`, args];
|
|
621
|
+
exprs = Array.isArray(exprs) ? exprs : [exprs];
|
|
622
|
+
let text = `GROUP_CONCAT(${options.distinct ? 'DISTINCT ' : ''}${exprs.map(() => '?').join(', ')}`;
|
|
623
|
+
const args = [...exprs];
|
|
624
|
+
if (options.orderBy !== undefined) {
|
|
625
|
+
const [orderBySql, orderByArgs] = buildOrderBy(name, options.orderBy);
|
|
626
|
+
text += ` ORDER BY ${orderBySql}`;
|
|
627
|
+
args.push(...orderByArgs);
|
|
628
|
+
}
|
|
629
|
+
if (options.separator !== undefined) {
|
|
630
|
+
text += ' SEPARATOR ?';
|
|
631
|
+
args.push(options.separator);
|
|
632
|
+
}
|
|
633
|
+
return [`${text})`, args];
|
|
685
634
|
}
|
|
686
|
-
|
|
687
635
|
// `orderBy` of `groupConcat()` and `over()`: a column, `[column, 'desc']` or a
|
|
688
636
|
// list of them. Strings are column names.
|
|
689
637
|
function buildOrderBy(name, orderBy) {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
args.push(toColumn(it[0]));
|
|
707
|
-
return `? ${keyword(name, 'direction', it[1], DIRECTIONS)}`;
|
|
638
|
+
const list = Array.isArray(orderBy) && !isOrderByPair(orderBy) ? orderBy : [orderBy];
|
|
639
|
+
const args = [];
|
|
640
|
+
const sql = list
|
|
641
|
+
.map((it) => {
|
|
642
|
+
if (!Array.isArray(it)) {
|
|
643
|
+
args.push(toColumn(it));
|
|
644
|
+
return '?';
|
|
645
|
+
}
|
|
646
|
+
if (it.length !== 2) {
|
|
647
|
+
throw new Error(`${label(name)}: invalid orderBy item. Use a column or [column, 'asc' | 'desc'].`);
|
|
648
|
+
}
|
|
649
|
+
args.push(toColumn(it[0]));
|
|
650
|
+
return `? ${keyword(name, 'direction', it[1], DIRECTIONS)}`;
|
|
708
651
|
})
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
return [sql, args];
|
|
652
|
+
.join(', ');
|
|
653
|
+
return [sql, args];
|
|
712
654
|
}
|
|
713
|
-
|
|
714
655
|
function toColumn(column) {
|
|
715
|
-
|
|
656
|
+
return typeof column === 'string' ? ref(column) : column;
|
|
716
657
|
}
|
|
717
|
-
|
|
718
658
|
function buildNtile(name, sql, [buckets]) {
|
|
719
|
-
|
|
659
|
+
return [`NTILE(${integer(name, 'buckets', buckets, 1)})`, []];
|
|
720
660
|
}
|
|
721
|
-
|
|
722
661
|
function buildLagOrLead(name, sql, [value, offset, defaultValue]) {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
return [`${sql}(?, ${offset})`, [value]];
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
return [`${sql}(?, ${offset}, ?)`, [value, defaultValue]];
|
|
662
|
+
if (offset === undefined && defaultValue === undefined) {
|
|
663
|
+
return [`${sql}(?)`, [value]];
|
|
664
|
+
}
|
|
665
|
+
offset = offset === undefined ? 1 : integer(name, 'offset', offset, 0);
|
|
666
|
+
if (defaultValue === undefined) {
|
|
667
|
+
return [`${sql}(?, ${offset})`, [value]];
|
|
668
|
+
}
|
|
669
|
+
return [`${sql}(?, ${offset}, ?)`, [value, defaultValue]];
|
|
734
670
|
}
|
|
735
|
-
|
|
736
671
|
function buildNthValue(name, sql, [value, n]) {
|
|
737
|
-
|
|
672
|
+
return [`NTH_VALUE(?, ${integer(name, 'n', n, 1)})`, [value]];
|
|
738
673
|
}
|
|
739
|
-
|
|
740
674
|
// The integer arguments of window functions are checked and written into the
|
|
741
675
|
// sql, since they are part of the syntax rather than values.
|
|
742
676
|
function integer(name, what, value, min) {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
return value;
|
|
677
|
+
if (!Number.isInteger(value) || value < min) {
|
|
678
|
+
throw new Error(`fn.${name}(): ${what} must be an integer >= ${min}, got ${JSON.stringify(value)}`);
|
|
679
|
+
}
|
|
680
|
+
return value;
|
|
750
681
|
}
|
|
751
|
-
|
|
752
682
|
// `[column, 'desc']`, as opposed to a list of two columns.
|
|
753
683
|
function isOrderByPair(it) {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
DIRECTIONS.includes(it[1].trim().toUpperCase())
|
|
759
|
-
);
|
|
684
|
+
return (Array.isArray(it) &&
|
|
685
|
+
it.length === 2 &&
|
|
686
|
+
typeof it[1] === 'string' &&
|
|
687
|
+
DIRECTIONS.includes(it[1].trim().toUpperCase()));
|
|
760
688
|
}
|
|
761
|
-
|
|
762
689
|
function buildJsonValue(name, sql, [doc, path, options = {}]) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
return [`JSON_VALUE(?, ? RETURNING ${options.returning.trim().toUpperCase()})`, [doc, path]];
|
|
690
|
+
if (options.returning === undefined) {
|
|
691
|
+
return ['JSON_VALUE(?, ?)', [doc, path]];
|
|
692
|
+
}
|
|
693
|
+
if (typeof options.returning !== 'string' || !CAST_TYPE.test(options.returning.trim())) {
|
|
694
|
+
throw new Error(`fn.jsonValue(): invalid type ${JSON.stringify(options.returning)}`);
|
|
695
|
+
}
|
|
696
|
+
return [`JSON_VALUE(?, ? RETURNING ${options.returning.trim().toUpperCase()})`, [doc, path]];
|
|
772
697
|
}
|
|
773
|
-
|
|
774
698
|
function buildMemberOf(name, sql, [value, array]) {
|
|
775
|
-
|
|
699
|
+
return ['(? MEMBER OF(?))', [value, array]];
|
|
776
700
|
}
|
|
777
|
-
|
|
778
701
|
function buildJsonObject(name, sql, args) {
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
return [`JSON_OBJECT(${args.map(() => '?').join(', ')})`, args];
|
|
702
|
+
// `fn.jsonObject({ a: ref('a'), b: 1 })` is `JSON_OBJECT('a', a, 'b', 1)`.
|
|
703
|
+
if (args.length === 1 && isPlainObjectArg(args[0])) {
|
|
704
|
+
args = Object.entries(args[0]).flat();
|
|
705
|
+
}
|
|
706
|
+
return [`JSON_OBJECT(${args.map(() => '?').join(', ')})`, args];
|
|
785
707
|
}
|
|
786
|
-
|
|
787
708
|
function isPlainObjectArg(value) {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
(value.constructor === Object || value.constructor === undefined)
|
|
792
|
-
);
|
|
709
|
+
return (value !== null &&
|
|
710
|
+
typeof value === 'object' &&
|
|
711
|
+
(value.constructor === Object || value.constructor === undefined));
|
|
793
712
|
}
|
|
794
|
-
|
|
795
713
|
// `name` is the name of an `fn` helper, or a method like `over()`.
|
|
796
714
|
function label(name) {
|
|
797
|
-
|
|
715
|
+
return name.endsWith('()') ? name : `fn.${name}()`;
|
|
798
716
|
}
|
|
799
|
-
|
|
800
717
|
function keyword(name, what, value, allowed) {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
return upper;
|
|
718
|
+
const upper = typeof value === 'string' ? value.trim().toUpperCase() : null;
|
|
719
|
+
if (!allowed.includes(upper)) {
|
|
720
|
+
throw new Error(`${label(name)}: invalid ${what} ${JSON.stringify(value)}. Use one of ${allowed.join(', ')}.`);
|
|
721
|
+
}
|
|
722
|
+
return upper;
|
|
810
723
|
}
|
|
811
|
-
|
|
724
|
+
// The helpers MariaDB (10.6 and 11.4) can't run as MySQL writes them. Each
|
|
725
|
+
// returns why for the given arguments, or null. A query built for MariaDB throws
|
|
726
|
+
// the reason instead of sending SQL MariaDB rejects.
|
|
727
|
+
const DOESNT_EXIST = () => "doesn't exist on MariaDB";
|
|
728
|
+
const MAX_ARGS = (max) => (args) => args.length > max ? `takes at most ${max} arguments on MariaDB` : null;
|
|
729
|
+
const MARIADB_UNSUPPORTED = {
|
|
730
|
+
regexpLike: DOESNT_EXIST,
|
|
731
|
+
memberOf: DOESNT_EXIST,
|
|
732
|
+
anyValue: DOESNT_EXIST,
|
|
733
|
+
grouping: DOESNT_EXIST,
|
|
734
|
+
uuidToBin: DOESNT_EXIST,
|
|
735
|
+
binToUuid: DOESNT_EXIST,
|
|
736
|
+
isUuid: DOESNT_EXIST,
|
|
737
|
+
icuVersion: DOESNT_EXIST,
|
|
738
|
+
rolesGraphml: DOESNT_EXIST,
|
|
739
|
+
statementDigest: DOESNT_EXIST,
|
|
740
|
+
statementDigestText: DOESNT_EXIST,
|
|
741
|
+
formatBytes: DOESNT_EXIST,
|
|
742
|
+
psCurrentThreadId: DOESNT_EXIST,
|
|
743
|
+
psThreadId: DOESNT_EXIST,
|
|
744
|
+
gtidSubset: DOESNT_EXIST,
|
|
745
|
+
gtidSubtract: DOESNT_EXIST,
|
|
746
|
+
waitForExecutedGtidSet: DOESNT_EXIST,
|
|
747
|
+
sourcePosWait: DOESNT_EXIST,
|
|
748
|
+
jsonSchemaValidationReport: DOESNT_EXIST,
|
|
749
|
+
jsonStorageFree: DOESNT_EXIST,
|
|
750
|
+
jsonStorageSize: DOESNT_EXIST,
|
|
751
|
+
regexpInstr: MAX_ARGS(2),
|
|
752
|
+
regexpSubstr: MAX_ARGS(2),
|
|
753
|
+
regexpReplace: MAX_ARGS(3),
|
|
754
|
+
jsonValue: (args) => args[2] && args[2].returning !== undefined ? "can't use the returning option on MariaDB" : null,
|
|
755
|
+
};
|
|
812
756
|
module.exports = {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
757
|
+
FUNCTIONS,
|
|
758
|
+
MARIADB_UNSUPPORTED,
|
|
759
|
+
buildOrderBy,
|
|
760
|
+
INTERVAL_UNITS,
|
|
761
|
+
TIMESTAMP_UNITS,
|
|
817
762
|
};
|