Casts

This section describes introspection of EdgeDB type casts. Features like whether the casts are implicit can be discovered by introspecting schema::Cast.

Introspection of the schema::Cast:


1. db>
2. ...
3. ...
4. ...
5. ...
6. ...
7. ...
8. ...
9. ...
10. ...
11. ...


1. with module schema
2. select ObjectType {
3. name,
4. links: {
5. name,
6. },
7. properties: {
8. name,
9. }
10. }
11. filter .name = 'schema::Cast';


1. {
2. Object {
3. name: 'schema::Cast',
4. links: {
5. Object { name: '__type__' },
6. Object { name: 'from_type' },
7. Object { name: 'to_type' }
8. },
9. properties: {
10. Object { name: 'allow_assignment' },
11. Object { name: 'allow_implicit' },
12. Object { name: 'id' },
13. Object { name: 'name' }
14. }
15. }
16. }

Introspection of the possible casts from std::int64 to other types:


1. db>
2. ...
3. ...
4. ...
5. ...
6. ...
7. ...
8. ...


1. with module schema
2. select Cast {
3. allow_assignment,
4. allow_implicit,
5. to_type: { name },
6. }
7. filter .from_type.name = 'std::int64'
8. order by .to_type.name;


1. {
2. Object {
3. allow_assignment: false,
4. allow_implicit: true,
5. to_type: Object { name: 'std::bigint' }
6. },
7. Object {
8. allow_assignment: false,
9. allow_implicit: true,
10. to_type: Object { name: 'std::decimal' }
11. },
12. Object {
13. allow_assignment: true,
14. allow_implicit: false,
15. to_type: Object { name: 'std::float32' }
16. },
17. Object {
18. allow_assignment: false,
19. allow_implicit: true,
20. to_type: Object { name: 'std::float64' }
21. },
22. Object {
23. allow_assignment: true,
24. allow_implicit: false,
25. to_type: Object { name: 'std::int16' }
26. },
27. Object {
28. allow_assignment: true,
29. allow_implicit: false,
30. to_type: Object { name: 'std::int32' }
31. },
32. Object {
33. allow_assignment: false,
34. allow_implicit: false,
35. to_type: Object { name: 'std::json' }
36. },
37. Object {
38. allow_assignment: false,
39. allow_implicit: false,
40. to_type: Object { name: 'std::str' }
41. }
42. }

The allow_implicit property tells whether this is an implicit cast in all contexts (such as when determining the type of a set of mixed literals or resolving the argument types of functions or operators if there’s no exact match). For example, a literal 1 is an int64 and it is implicitly cast into a bigint or float64 if it is added to a set containing either one of those types:


1. db>


1. select {1, 2n};


1. {1n, 2n}


1. db>


1. select {1, 2.0};


1. {1.0, 2.0}

What happens if there’s no implicit cast between a couple of scalars in this type of example? EdgeDB checks whether there’s a scalar type such that all of the set elements can be implicitly cast into that:


1. db>


1. select introspect (typeof {<int64>1, <float32>2}).name;


1. {'std::float64'}

The scalar types int64 and float32 cannot be implicitly cast into each other, but they both can be implicitly cast into float64.

The allow_assignment property tells whether this is an implicit cast during assignment if a more general implicit cast is not allowed. For example, consider the following type:


1. type Example {
2. property p_int16 -> int16;
3. property p_float32 -> float32;
4. property p_json -> json;
5. }


1. db>
2. ...
3. ...
4. ...


1. insert Example {
2. p_int16 := 1,
3. p_float32 := 2
4. };


1. {Object { id: <uuid>'...' }}


1. db>
2. ...
3. ...


1. insert Example {
2. p_json := 3  # assignment cast to json not allowed
3. };


1. InvalidPropertyTargetError: invalid target for property
2. 'p_json' of object type 'default::Example': 'std::int64'
3. (expecting 'std::json')