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