Open andyDoucette opened 2 years ago
The issue is a little bit more difficult. You can have two situations. First, you design a struct without types. Then you are free to give back what you want. If you have a struct with defined types you are in trouble. There you can have nulls in your result set. If they aren't defined by Union type with Nothing as one type inside you will run into an error. A thought which comes to my mind would be to use a macro to extend the structs type. But that's not the best fit because somebody who wants to use the variables inside the struct directly don't want deal everywhere with Union types. So I think the only way would be to deal with user defined Union types which deal with fields which can be null in the result set. I think I've made something similar in the past. I will have a look at some code which was not accepted for an PR.
The issue is that union types are not proper types (or at least I'm not aware of reflection APIs for union types).
Let's take this example:
y::Union{Number,Nothing} = nothing
How do we determine the type of y
?
julia> y::Union{Number,Nothing} = nothing
julia> typeof(y)
Nothing
-> Julia does not tell us that y
is a Union.
So how can SearchLight know into what types to try and convert?
Your example isn't chosen properly for the context we are in Searchlight. To determine the type of a field of a struct you have to look at the whole struct and then you will see the Union type of the field. If you try this on the level of the field itself it will fail as you stated above. In this context you are absolutely right. On the level of the field your example only says: "Numbers and Nothing are allowed", not more. I've done something similar in my package TypeDBORM where such question comes also in my mind. Determine Types in a Union isn't that hard. Union is build like a linked list. Each Union type has a field a and a field b. If there are more than two types b will be also a Union and the game begins again. So testing if there are only two types and one of them is Nothing isn't that hard. It took me 3 lines to get it work. Not nice, not fast, but it works.
Your example isn't chosen properly for the context we are in Searchlight. To determine the type of a field of a struct you have to look at the whole struct and then you will see the Union type of the field.
Can you show an example of this?
I'm still trying to get all() to work with this resource.
As a work-around to that first issue, I'm using this code temporarily, although it totally isn't right (I shouldn't be allowing the making of models that are invalid).
The issue I'm having now is with the end_time field.
Digging into the SearchLight here's the relevant to_model() code in SearchLight.j:
So, basically, on line 498, SearchLight makes an empty struct, and then later it tries to set the fields using oftype(getfield(_m, unq_field), value). In other words, it looks at the type of each field in the initialized object and assumes that everything we ever put in that field will be of the same type. But, what about Unions? They can hold different types. So here we have a case where we initialized to nothing, but we tried to put a DateTime in it's place instead. That's totally valid according to the struct, but the way that to_model is making the assumption that "once a T, always a T" doesn't seem right when Unions are involved. I really hope I'm doing something dumb at this point, because being able to make a field in a database NULLable doesn't seem like a radical thing, yet everywhere I turn there's a new error message and more of other people's code to read to figure out why. 😢