• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codenotary / immudb / 18752576117

23 Oct 2025 02:55PM UTC coverage: 89.257% (+0.01%) from 89.247%
18752576117

Pull #2076

gh-ci

els-tmiller
enable fargate credentials

Signed-off-by: Tim Miller <tim.miller@elsevier.com>
Pull Request #2076: S3 Storage - Fargate Credentials

452 of 493 new or added lines in 8 files covered. (91.68%)

412 existing lines in 4 files now uncovered.

37970 of 42540 relevant lines covered (89.26%)

149626.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.02
/embedded/sql/functions.go
1
/*
2
Copyright 2025 Codenotary Inc. All rights reserved.
3

4
SPDX-License-Identifier: BUSL-1.1
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    https://mariadb.com/bsl11/
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package sql
18

19
import (
20
        "fmt"
21
        "strings"
22
        "time"
23

24
        "github.com/google/uuid"
25
)
26

27
const (
28
        CoalesceFnCall           string = "COALESCE"
29
        LengthFnCall             string = "LENGTH"
30
        SubstringFnCall          string = "SUBSTRING"
31
        ConcatFnCall             string = "CONCAT"
32
        LowerFnCall              string = "LOWER"
33
        UpperFnCall              string = "UPPER"
34
        TrimFnCall               string = "TRIM"
35
        NowFnCall                string = "NOW"
36
        UUIDFnCall               string = "RANDOM_UUID"
37
        DatabasesFnCall          string = "DATABASES"
38
        TablesFnCall             string = "TABLES"
39
        TableFnCall              string = "TABLE"
40
        UsersFnCall              string = "USERS"
41
        ColumnsFnCall            string = "COLUMNS"
42
        IndexesFnCall            string = "INDEXES"
43
        GrantsFnCall             string = "GRANTS"
44
        JSONTypeOfFnCall         string = "JSON_TYPEOF"
45
        PGGetUserByIDFnCall      string = "PG_GET_USERBYID"
46
        PgTableIsVisibleFnCall   string = "PG_TABLE_IS_VISIBLE"
47
        PgShobjDescriptionFnCall string = "SHOBJ_DESCRIPTION"
48
)
49

50
var builtinFunctions = map[string]Function{
51
        CoalesceFnCall:           &CoalesceFn{},
52
        LengthFnCall:             &LengthFn{},
53
        SubstringFnCall:          &SubstringFn{},
54
        ConcatFnCall:             &ConcatFn{},
55
        LowerFnCall:              &LowerUpperFnc{},
56
        UpperFnCall:              &LowerUpperFnc{isUpper: true},
57
        TrimFnCall:               &TrimFnc{},
58
        NowFnCall:                &NowFn{},
59
        UUIDFnCall:               &UUIDFn{},
60
        JSONTypeOfFnCall:         &JsonTypeOfFn{},
61
        PGGetUserByIDFnCall:      &pgGetUserByIDFunc{},
62
        PgTableIsVisibleFnCall:   &pgTableIsVisible{},
63
        PgShobjDescriptionFnCall: &pgShobjDescription{},
64
}
65

66
type Function interface {
67
        RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error
68
        InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error)
69
        Apply(tx *SQLTx, params []TypedValue) (TypedValue, error)
70
}
71

72
type CoalesceFn struct{}
73

NEW
74
func (f *CoalesceFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
×
NEW
75
        return AnyType, nil
×
NEW
76
}
×
77

NEW
78
func (f *CoalesceFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
×
NEW
79
        return nil
×
NEW
80
}
×
81

82
func (f *CoalesceFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
5✔
83
        t := AnyType
5✔
84

5✔
85
        for _, p := range params {
17✔
86
                if !p.IsNull() {
20✔
87
                        if t == AnyType {
11✔
88
                                t = p.Type()
3✔
89
                        } else if p.Type() != t && !(IsNumericType(t) && IsNumericType(p.Type())) {
9✔
90
                                return nil, fmt.Errorf("coalesce: %w", ErrInvalidTypes)
1✔
91
                        }
1✔
92
                }
93
        }
94

95
        for _, p := range params {
10✔
96
                if !p.IsNull() {
8✔
97
                        return p, nil
2✔
98
                }
2✔
99
        }
100
        return NewNull(t), nil
2✔
101
}
102

103
// -------------------------------------
104
// String Functions
105
// -------------------------------------
106

107
type LengthFn struct{}
108

109
func (f *LengthFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
110
        return IntegerType, nil
1✔
111
}
1✔
112

113
func (f *LengthFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
114
        if t != IntegerType {
3✔
115
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, IntegerType, t)
1✔
116
        }
1✔
117
        return nil
1✔
118
}
119

120
func (f *LengthFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
5✔
121
        if len(params) != 1 {
6✔
122
                return nil, fmt.Errorf("%w: '%s' function does expects one argument but %d were provided", ErrIllegalArguments, LengthFnCall, len(params))
1✔
123
        }
1✔
124

125
        v := params[0]
4✔
126
        if v.IsNull() {
5✔
127
                return &NullValue{t: IntegerType}, nil
1✔
128
        }
1✔
129

130
        if v.Type() != VarcharType {
4✔
131
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type %s", ErrIllegalArguments, LengthFnCall, VarcharType)
1✔
132
        }
1✔
133

134
        s, _ := v.RawValue().(string)
2✔
135
        return &Integer{val: int64(len(s))}, nil
2✔
136
}
137

138
type ConcatFn struct{}
139

140
func (f *ConcatFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
141
        return VarcharType, nil
1✔
142
}
1✔
143

144
func (f *ConcatFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
145
        if t != VarcharType {
3✔
146
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
1✔
147
        }
1✔
148
        return nil
1✔
149
}
150

151
func (f *ConcatFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
4✔
152
        if len(params) == 0 {
5✔
153
                return nil, fmt.Errorf("%w: '%s' function does expects at least one argument", ErrIllegalArguments, ConcatFnCall)
1✔
154
        }
1✔
155

156
        for _, v := range params {
14✔
157
                if v.Type() != AnyType && v.Type() != VarcharType {
12✔
158
                        return nil, fmt.Errorf("%w: '%s' function doesn't accept arguments of type %s", ErrIllegalArguments, ConcatFnCall, v.Type())
1✔
159
                }
1✔
160
        }
161

162
        var builder strings.Builder
2✔
163
        for _, v := range params {
10✔
164
                s, _ := v.RawValue().(string)
8✔
165
                builder.WriteString(s)
8✔
166
        }
8✔
167
        return &Varchar{val: builder.String()}, nil
2✔
168
}
169

170
type SubstringFn struct {
171
}
172

173
func (f *SubstringFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
174
        return VarcharType, nil
1✔
175
}
1✔
176

177
func (f *SubstringFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
178
        if t != VarcharType {
3✔
179
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
1✔
180
        }
1✔
181
        return nil
1✔
182
}
183

184
func (f *SubstringFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
7✔
185
        if len(params) != 3 {
8✔
186
                return nil, fmt.Errorf("%w: '%s' function does expects three argument but %d were provided", ErrIllegalArguments, SubstringFnCall, len(params))
1✔
187
        }
1✔
188

189
        v1, v2, v3 := params[0], params[1], params[2]
6✔
190

6✔
191
        if v1.IsNull() || v2.IsNull() || v3.IsNull() {
7✔
192
                return &NullValue{t: VarcharType}, nil
1✔
193
        }
1✔
194

195
        s, _ := v1.RawValue().(string)
5✔
196
        pos, _ := v2.RawValue().(int64)
5✔
197
        length, _ := v3.RawValue().(int64)
5✔
198

5✔
199
        if pos <= 0 {
6✔
200
                return nil, fmt.Errorf("%w: parameter 'position' must be greater than zero", ErrIllegalArguments)
1✔
201
        }
1✔
202

203
        if length < 0 {
5✔
204
                return nil, fmt.Errorf("%w: parameter 'length' cannot be negative", ErrIllegalArguments)
1✔
205
        }
1✔
206

207
        if pos-1 >= int64(len(s)) {
3✔
UNCOV
208
                return &Varchar{val: ""}, nil
×
UNCOV
209
        }
×
210

211
        end := pos - 1 + length
3✔
212
        if end > int64(len(s)) {
4✔
213
                end = int64(len(s))
1✔
214
        }
1✔
215
        return &Varchar{val: s[pos-1 : end]}, nil
3✔
216
}
217

218
type LowerUpperFnc struct {
219
        isUpper bool
220
}
221

222
func (f *LowerUpperFnc) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
2✔
223
        return VarcharType, nil
2✔
224
}
2✔
225

226
func (f *LowerUpperFnc) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
3✔
227
        if t != VarcharType {
4✔
228
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
1✔
229
        }
1✔
230
        return nil
2✔
231
}
232

233
func (f *LowerUpperFnc) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
6✔
234
        if len(params) != 1 {
7✔
235
                return nil, fmt.Errorf("%w: '%s' function does expects one argument but %d were provided", ErrIllegalArguments, f.name(), len(params))
1✔
236
        }
1✔
237

238
        v := params[0]
5✔
239
        if v.IsNull() {
7✔
240
                return &NullValue{t: VarcharType}, nil
2✔
241
        }
2✔
242

243
        if v.Type() != VarcharType {
4✔
244
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type %s", ErrIllegalArguments, f.name(), VarcharType)
1✔
245
        }
1✔
246

247
        s, _ := v.RawValue().(string)
2✔
248

2✔
249
        var res string
2✔
250
        if f.isUpper {
3✔
251
                res = strings.ToUpper(s)
1✔
252
        } else {
2✔
253
                res = strings.ToLower(s)
1✔
254
        }
1✔
255
        return &Varchar{val: res}, nil
2✔
256
}
257

258
func (f *LowerUpperFnc) name() string {
2✔
259
        if f.isUpper {
3✔
260
                return UpperFnCall
1✔
261
        }
1✔
262
        return LowerFnCall
1✔
263
}
264

265
type TrimFnc struct {
266
}
267

268
func (f *TrimFnc) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
269
        return VarcharType, nil
1✔
270
}
1✔
271

272
func (f *TrimFnc) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
273
        if t != VarcharType {
3✔
274
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
1✔
275
        }
1✔
276
        return nil
1✔
277
}
278

279
func (f *TrimFnc) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
4✔
280
        if len(params) != 1 {
5✔
281
                return nil, fmt.Errorf("%w: '%s' function does expects one argument but %d were provided", ErrIllegalArguments, TrimFnCall, len(params))
1✔
282
        }
1✔
283

284
        v := params[0]
3✔
285
        if v.IsNull() {
4✔
286
                return &NullValue{t: VarcharType}, nil
1✔
287
        }
1✔
288

289
        if v.Type() != VarcharType {
3✔
290
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type %s", ErrIllegalArguments, TrimFnCall, VarcharType)
1✔
291
        }
1✔
292

293
        s, _ := v.RawValue().(string)
1✔
294
        return &Varchar{val: strings.Trim(s, " \t\n\r\v\f")}, nil
1✔
295
}
296

297
// -------------------------------------
298
// Time Functions
299
// -------------------------------------
300

301
type NowFn struct{}
302

303
func (f *NowFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
15✔
304
        return TimestampType, nil
15✔
305
}
15✔
306

307
func (f *NowFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
4✔
308
        if t != TimestampType {
5✔
309
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, TimestampType, t)
1✔
310
        }
1✔
311
        return nil
3✔
312
}
313

314
func (f *NowFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
97✔
315
        if len(params) > 0 {
98✔
316
                return nil, fmt.Errorf("%w: '%s' function does not expect any argument but %d were provided", ErrIllegalArguments, NowFnCall, len(params))
1✔
317
        }
1✔
318
        return &Timestamp{val: tx.Timestamp().Truncate(time.Microsecond).UTC()}, nil
96✔
319
}
320

321
// -------------------------------------
322
// JSON Functions
323
// -------------------------------------
324

325
type JsonTypeOfFn struct{}
326

327
func (f *JsonTypeOfFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
328
        return VarcharType, nil
1✔
329
}
1✔
330

331
func (f *JsonTypeOfFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
332
        if t != VarcharType {
3✔
333
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
1✔
334
        }
1✔
335
        return nil
1✔
336
}
337

338
func (f *JsonTypeOfFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
304✔
339
        if len(params) != 1 {
305✔
340
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, JSONTypeOfFnCall, 1, len(params))
1✔
341
        }
1✔
342

343
        v := params[0]
303✔
344
        if v.IsNull() {
304✔
345
                return NewNull(AnyType), nil
1✔
346
        }
1✔
347

348
        jsonVal, ok := v.(*JSON)
302✔
349
        if !ok {
303✔
350
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type JSON", ErrIllegalArguments, JSONTypeOfFnCall)
1✔
351
        }
1✔
352
        return NewVarchar(jsonVal.primitiveType()), nil
301✔
353
}
354

355
// -------------------------------------
356
// UUID Functions
357
// -------------------------------------
358

359
type UUIDFn struct{}
360

361
func (f *UUIDFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
362
        return UUIDType, nil
1✔
363
}
1✔
364

365
func (f *UUIDFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
366
        if t != UUIDType {
3✔
367
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, UUIDType, t)
1✔
368
        }
1✔
369
        return nil
1✔
370
}
371

372
func (f *UUIDFn) Apply(_ *SQLTx, params []TypedValue) (TypedValue, error) {
5✔
373
        if len(params) > 0 {
6✔
374
                return nil, fmt.Errorf("%w: '%s' function does not expect any argument but %d were provided", ErrIllegalArguments, UUIDFnCall, len(params))
1✔
375
        }
1✔
376
        return &UUID{val: uuid.New()}, nil
4✔
377
}
378

379
// pg functions
380

381
type pgGetUserByIDFunc struct{}
382

383
func (f *pgGetUserByIDFunc) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
384
        if t != VarcharType {
3✔
385
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, IntegerType, t)
1✔
386
        }
1✔
387
        return nil
1✔
388
}
389

390
func (f *pgGetUserByIDFunc) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
391
        return VarcharType, nil
1✔
392
}
1✔
393

394
func (f *pgGetUserByIDFunc) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
2✔
395
        if len(params) != 1 {
3✔
396
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, PGGetUserByIDFnCall, 1, len(params))
1✔
397
        }
1✔
398

399
        if params[0].RawValue() != int64(0) {
2✔
400
                return nil, fmt.Errorf("user not found")
1✔
401
        }
1✔
402

UNCOV
403
        users, err := tx.ListUsers(tx.tx.Context())
×
UNCOV
404
        if err != nil {
×
UNCOV
405
                return nil, err
×
UNCOV
406
        }
×
407

UNCOV
408
        idx := findSysAdmin(users)
×
UNCOV
409
        if idx < 0 {
×
UNCOV
410
                return nil, fmt.Errorf("admin not found")
×
UNCOV
411
        }
×
UNCOV
412
        return NewVarchar(users[idx].Username()), nil
×
413
}
414

UNCOV
415
func findSysAdmin(users []User) int {
×
UNCOV
416
        for i, u := range users {
×
UNCOV
417
                if u.Permission() == PermissionSysAdmin {
×
UNCOV
418
                        return i
×
UNCOV
419
                }
×
420
        }
UNCOV
421
        return -1
×
422
}
423

424
type pgTableIsVisible struct{}
425

426
func (f *pgTableIsVisible) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
427
        if t != BooleanType {
3✔
428
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, BooleanType, t)
1✔
429
        }
1✔
430
        return nil
1✔
431
}
432

433
func (f *pgTableIsVisible) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
434
        return BooleanType, nil
1✔
435
}
1✔
436

437
func (f *pgTableIsVisible) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
2✔
438
        if len(params) != 1 {
3✔
439
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, PgTableIsVisibleFnCall, 1, len(params))
1✔
440
        }
1✔
441
        return NewBool(true), nil
1✔
442
}
443

444
type pgShobjDescription struct{}
445

446
func (f *pgShobjDescription) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
2✔
447
        if t != VarcharType {
3✔
448
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
1✔
449
        }
1✔
450
        return nil
1✔
451
}
452

453
func (f *pgShobjDescription) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
454
        return VarcharType, nil
1✔
455
}
1✔
456

457
func (f *pgShobjDescription) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
2✔
458
        if len(params) != 2 {
3✔
459
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, PgShobjDescriptionFnCall, 2, len(params))
1✔
460
        }
1✔
461
        return NewVarchar(""), nil
1✔
462
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc