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. 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. 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. select {1, 2n};
1. {1n, 2n}
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. 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. insert Example {
2. p_int16 := 1,
3. p_float32 := 2
4. };
1. {Object { id: <uuid>'...' }}
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')
