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

codenotary / immudb / 18658094170

20 Oct 2025 04:13PM UTC coverage: 89.267% (+0.002%) from 89.265%
18658094170

Pull #2076

gh-ci

els-tmiller
fix spacing
Pull Request #2076: S3 Storage - Fargate Credentials

16 of 17 new or added lines in 4 files covered. (94.12%)

452 existing lines in 4 files now uncovered.

37974 of 42540 relevant lines covered (89.27%)

149951.18 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
        LengthFnCall             string = "LENGTH"
29
        SubstringFnCall          string = "SUBSTRING"
30
        ConcatFnCall             string = "CONCAT"
31
        LowerFnCall              string = "LOWER"
32
        UpperFnCall              string = "UPPER"
33
        TrimFnCall               string = "TRIM"
34
        NowFnCall                string = "NOW"
35
        UUIDFnCall               string = "RANDOM_UUID"
36
        DatabasesFnCall          string = "DATABASES"
37
        TablesFnCall             string = "TABLES"
38
        TableFnCall              string = "TABLE"
39
        UsersFnCall              string = "USERS"
40
        ColumnsFnCall            string = "COLUMNS"
41
        IndexesFnCall            string = "INDEXES"
42
        GrantsFnCall             string = "GRANTS"
43
        JSONTypeOfFnCall         string = "JSON_TYPEOF"
44
        PGGetUserByIDFnCall      string = "PG_GET_USERBYID"
45
        PgTableIsVisibleFnCall   string = "PG_TABLE_IS_VISIBLE"
46
        PgShobjDescriptionFnCall string = "SHOBJ_DESCRIPTION"
47
)
48

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

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

70
// -------------------------------------
71
// String Functions
72
// -------------------------------------
73

UNCOV
74
type LengthFn struct{}
×
UNCOV
75

×
UNCOV
76
func (f *LengthFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
×
77
        return IntegerType, nil
UNCOV
78
}
×
UNCOV
79

×
UNCOV
80
func (f *LengthFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
×
81
        if t != IntegerType {
82
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, IntegerType, t)
5✔
83
        }
5✔
84
        return nil
5✔
85
}
17✔
86

20✔
87
func (f *LengthFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
11✔
88
        if len(params) != 1 {
3✔
89
                return nil, fmt.Errorf("%w: '%s' function does expects one argument but %d were provided", ErrIllegalArguments, LengthFnCall, len(params))
9✔
90
        }
1✔
91

1✔
92
        v := params[0]
93
        if v.IsNull() {
94
                return &NullValue{t: IntegerType}, nil
95
        }
10✔
96

8✔
97
        if v.Type() != VarcharType {
2✔
98
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type %s", ErrIllegalArguments, LengthFnCall, VarcharType)
2✔
99
        }
100

2✔
101
        s, _ := v.RawValue().(string)
102
        return &Integer{val: int64(len(s))}, nil
103
}
104

105
type ConcatFn struct{}
106

107
func (f *ConcatFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
108
        return VarcharType, nil
109
}
1✔
110

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

1✔
118
func (f *ConcatFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
119
        if len(params) == 0 {
120
                return nil, fmt.Errorf("%w: '%s' function does expects at least one argument", ErrIllegalArguments, ConcatFnCall)
5✔
121
        }
6✔
122

1✔
123
        for _, v := range params {
1✔
124
                if v.Type() != AnyType && v.Type() != VarcharType {
125
                        return nil, fmt.Errorf("%w: '%s' function doesn't accept arguments of type %s", ErrIllegalArguments, ConcatFnCall, v.Type())
4✔
126
                }
5✔
127
        }
1✔
128

1✔
129
        var builder strings.Builder
130
        for _, v := range params {
4✔
131
                s, _ := v.RawValue().(string)
1✔
132
                builder.WriteString(s)
1✔
133
        }
134
        return &Varchar{val: builder.String()}, nil
2✔
135
}
2✔
136

137
type SubstringFn struct {
138
}
139

140
func (f *SubstringFn) 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 *SubstringFn) 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 *SubstringFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
4✔
152
        if len(params) != 3 {
5✔
153
                return nil, fmt.Errorf("%w: '%s' function does expects three argument but %d were provided", ErrIllegalArguments, SubstringFnCall, len(params))
1✔
154
        }
1✔
155

156
        v1, v2, v3 := params[0], params[1], params[2]
14✔
157

12✔
158
        if v1.IsNull() || v2.IsNull() || v3.IsNull() {
1✔
159
                return &NullValue{t: VarcharType}, nil
1✔
160
        }
161

162
        s, _ := v1.RawValue().(string)
2✔
163
        pos, _ := v2.RawValue().(int64)
10✔
164
        length, _ := v3.RawValue().(int64)
8✔
165

8✔
166
        if pos <= 0 {
8✔
167
                return nil, fmt.Errorf("%w: parameter 'position' must be greater than zero", ErrIllegalArguments)
2✔
168
        }
169

170
        if length < 0 {
171
                return nil, fmt.Errorf("%w: parameter 'length' cannot be negative", ErrIllegalArguments)
172
        }
173

1✔
174
        if pos-1 >= int64(len(s)) {
1✔
175
                return &Varchar{val: ""}, nil
1✔
176
        }
177

2✔
178
        end := pos - 1 + length
3✔
179
        if end > int64(len(s)) {
1✔
180
                end = int64(len(s))
1✔
181
        }
1✔
182
        return &Varchar{val: s[pos-1 : end]}, nil
183
}
184

7✔
185
type LowerUpperFnc struct {
8✔
186
        isUpper bool
1✔
187
}
1✔
188

189
func (f *LowerUpperFnc) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
6✔
190
        return VarcharType, nil
6✔
191
}
7✔
192

1✔
193
func (f *LowerUpperFnc) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
1✔
194
        if t != VarcharType {
195
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
5✔
196
        }
5✔
197
        return nil
5✔
198
}
5✔
199

6✔
200
func (f *LowerUpperFnc) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
1✔
201
        if len(params) != 1 {
1✔
202
                return nil, fmt.Errorf("%w: '%s' function does expects one argument but %d were provided", ErrIllegalArguments, f.name(), len(params))
203
        }
5✔
204

1✔
205
        v := params[0]
1✔
206
        if v.IsNull() {
207
                return &NullValue{t: VarcharType}, nil
3✔
UNCOV
208
        }
×
UNCOV
209

×
210
        if v.Type() != VarcharType {
211
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type %s", ErrIllegalArguments, f.name(), VarcharType)
3✔
212
        }
4✔
213

1✔
214
        s, _ := v.RawValue().(string)
1✔
215

3✔
216
        var res string
217
        if f.isUpper {
218
                res = strings.ToUpper(s)
219
        } else {
220
                res = strings.ToLower(s)
221
        }
222
        return &Varchar{val: res}, nil
2✔
223
}
2✔
224

2✔
225
func (f *LowerUpperFnc) name() string {
226
        if f.isUpper {
3✔
227
                return UpperFnCall
4✔
228
        }
1✔
229
        return LowerFnCall
1✔
230
}
2✔
231

232
type TrimFnc struct {
233
}
6✔
234

7✔
235
func (f *TrimFnc) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
236
        return VarcharType, nil
1✔
237
}
238

5✔
239
func (f *TrimFnc) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
7✔
240
        if t != VarcharType {
2✔
241
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
2✔
242
        }
243
        return nil
4✔
244
}
1✔
245

1✔
246
func (f *TrimFnc) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
247
        if len(params) != 1 {
2✔
248
                return nil, fmt.Errorf("%w: '%s' function does expects one argument but %d were provided", ErrIllegalArguments, TrimFnCall, len(params))
2✔
249
        }
2✔
250

3✔
251
        v := params[0]
1✔
252
        if v.IsNull() {
2✔
253
                return &NullValue{t: VarcharType}, nil
1✔
254
        }
1✔
255

2✔
256
        if v.Type() != VarcharType {
257
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type %s", ErrIllegalArguments, TrimFnCall, VarcharType)
258
        }
2✔
259

3✔
260
        s, _ := v.RawValue().(string)
1✔
261
        return &Varchar{val: strings.Trim(s, " \t\n\r\v\f")}, nil
1✔
262
}
1✔
263

264
// -------------------------------------
265
// Time Functions
266
// -------------------------------------
267

268
type NowFn struct{}
1✔
269

1✔
270
func (f *NowFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
271
        return TimestampType, nil
272
}
2✔
273

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

5✔
281
func (f *NowFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
1✔
282
        if len(params) > 0 {
1✔
283
                return nil, fmt.Errorf("%w: '%s' function does not expect any argument but %d were provided", ErrIllegalArguments, NowFnCall, len(params))
284
        }
3✔
285
        return &Timestamp{val: tx.Timestamp().Truncate(time.Microsecond).UTC()}, nil
4✔
286
}
1✔
287

1✔
288
// -------------------------------------
289
// JSON Functions
3✔
290
// -------------------------------------
1✔
291

1✔
292
type JsonTypeOfFn struct{}
293

1✔
294
func (f *JsonTypeOfFn) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
295
        return VarcharType, nil
296
}
297

298
func (f *JsonTypeOfFn) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
299
        if t != VarcharType {
300
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
301
        }
302
        return nil
303
}
15✔
304

15✔
305
func (f *JsonTypeOfFn) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
15✔
306
        if len(params) != 1 {
307
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, JSONTypeOfFnCall, 1, len(params))
4✔
308
        }
5✔
309

1✔
310
        v := params[0]
1✔
311
        if v.IsNull() {
3✔
312
                return NewNull(AnyType), nil
313
        }
314

97✔
315
        jsonVal, ok := v.(*JSON)
98✔
316
        if !ok {
1✔
317
                return nil, fmt.Errorf("%w: '%s' function expects an argument of type JSON", ErrIllegalArguments, JSONTypeOfFnCall)
1✔
318
        }
96✔
319
        return NewVarchar(jsonVal.primitiveType()), nil
320
}
321

322
// -------------------------------------
323
// UUID Functions
324
// -------------------------------------
325

326
type UUIDFn struct{}
327

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

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

304✔
339
func (f *UUIDFn) Apply(_ *SQLTx, params []TypedValue) (TypedValue, error) {
305✔
340
        if len(params) > 0 {
1✔
341
                return nil, fmt.Errorf("%w: '%s' function does not expect any argument but %d were provided", ErrIllegalArguments, UUIDFnCall, len(params))
1✔
342
        }
343
        return &UUID{val: uuid.New()}, nil
303✔
344
}
304✔
345

1✔
346
// pg functions
1✔
347

348
type pgGetUserByIDFunc struct{}
302✔
349

303✔
350
func (f *pgGetUserByIDFunc) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
1✔
351
        if t != VarcharType {
1✔
352
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, IntegerType, t)
301✔
353
        }
354
        return nil
355
}
356

357
func (f *pgGetUserByIDFunc) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
358
        return VarcharType, nil
359
}
360

361
func (f *pgGetUserByIDFunc) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
1✔
362
        if len(params) != 1 {
1✔
363
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, PGGetUserByIDFnCall, 1, len(params))
1✔
364
        }
365

2✔
366
        if params[0].RawValue() != int64(0) {
3✔
367
                return nil, fmt.Errorf("user not found")
1✔
368
        }
1✔
369

1✔
370
        users, err := tx.ListUsers(tx.tx.Context())
371
        if err != nil {
372
                return nil, err
5✔
373
        }
6✔
374

1✔
375
        idx := findSysAdmin(users)
1✔
376
        if idx < 0 {
4✔
377
                return nil, fmt.Errorf("admin not found")
378
        }
379
        return NewVarchar(users[idx].Username()), nil
380
}
381

382
func findSysAdmin(users []User) int {
383
        for i, u := range users {
2✔
384
                if u.Permission() == PermissionSysAdmin {
3✔
385
                        return i
1✔
386
                }
1✔
387
        }
1✔
388
        return -1
389
}
390

1✔
391
type pgTableIsVisible struct{}
1✔
392

1✔
393
func (f *pgTableIsVisible) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
394
        if t != BooleanType {
2✔
395
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, BooleanType, t)
3✔
396
        }
1✔
397
        return nil
1✔
398
}
399

2✔
400
func (f *pgTableIsVisible) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
1✔
401
        return BooleanType, nil
1✔
402
}
UNCOV
403

×
UNCOV
404
func (f *pgTableIsVisible) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
×
UNCOV
405
        if len(params) != 1 {
×
UNCOV
406
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, PgTableIsVisibleFnCall, 1, len(params))
×
407
        }
UNCOV
408
        return NewBool(true), nil
×
UNCOV
409
}
×
UNCOV
410

×
UNCOV
411
type pgShobjDescription struct{}
×
UNCOV
412

×
413
func (f *pgShobjDescription) RequiresType(t SQLValueType, cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) error {
414
        if t != VarcharType {
UNCOV
415
                return fmt.Errorf("%w: %v can not be interpreted as type %v", ErrInvalidTypes, VarcharType, t)
×
UNCOV
416
        }
×
UNCOV
417
        return nil
×
UNCOV
418
}
×
UNCOV
419

×
420
func (f *pgShobjDescription) InferType(cols map[string]ColDescriptor, params map[string]SQLValueType, implicitTable string) (SQLValueType, error) {
UNCOV
421
        return VarcharType, nil
×
422
}
423

424
func (f *pgShobjDescription) Apply(tx *SQLTx, params []TypedValue) (TypedValue, error) {
425
        if len(params) != 2 {
426
                return nil, fmt.Errorf("%w: '%s' function expects %d arguments but %d were provided", ErrIllegalArguments, PgShobjDescriptionFnCall, 2, len(params))
2✔
427
        }
3✔
428
        return NewVarchar(""), nil
1✔
429
}
1✔
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