-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PostgreSQL] Improve parsing support for postgresql data types #73
base: master
Are you sure you want to change the base?
Conversation
This is great @ntma! Way stabler approach to casting those default values 👍🏻 |
Glad you liked it @rijkvanzanten, but there are some caveats unfortunately. I'll try to post them as soon as possible and perhaps we can discuss a solution for them. |
Sounds good 👍🏻 |
The biggest caveat is that this PR works for the postgres built-in types, BUT array's are not considered a built-in. Hence their default values will be parsed as plain string's... Still, I believe we can make this PR work with a few adjustments. Hope I can be clear in the explanation. Intro for the solutionWhen retrieving column information,
Which means that To test this, run the following query for a table with a column of type array: SELECT
table_name,
column_name,
data_type, -- this will return ARRAY for array's
udt_name -- this will return the actual array type
FROM
information_schema.columns
WHERE
table_name = 'YOUR_TABLE_HERE'; Possible solutionThe idea is to start using the The first step would be adding the SELECT
oid, -- data type id
typname -- udt_name in the information_schema
FROM pg_type Then change the signature of parseDefaultValue from
And finally use the |
Woa, yeah that got way more complicated than I thought haha. Time to call in the cavalry. @Oreilles any thoughts on the matter? |
This is still fundamentally wrong anyway, because it cannot handle expression, eg. Another thing I think of is that since Postgres has built-in type casting, the actual column type might differ from the default value expression return type, which could there again crash the parser. So I think you'd still need to add something like try {
return parser(value);
catch(e) {
return type
} But I think it is a dark pattern to make the |
I didn't test it, but it will probably not crash because interval belongs to the set of built-ins in Which means we could get the proper parser for it: But yes, definitely needs a try/catch for some edge cases.
That's true... but I think you will need the column type in some cases. If we define a column of type boolean and default it to Regarding the |
It would not crash because the value is an interval, but because
This is misleading, because you then couldn't make the difference between a field that actually doesn't have a default value, and a field of which you just couldn't resolve the default value expression to a javascript object. |
Wondering if we should return a "defaultValueRaw" that doesn't do any parsing magic next to the "defaultValue" that does a best effort to parse it into a workable JS value 🤔 |
I think that's the best solution |
And should we only focus built-in types for now? |
I think so 🤔 I'm having some trouble imagining how we'd even be able to support non-built-ins, as there's a theoretical infinite amount of them |
Alright, I'll make it simple then 👍 |
… types map for information_schema.data_type | updated unit tests
Hello guys, Sorry for the delay in the development but I've been extremely busy in the last weeks. So, with this last commit I added:
If everyone agrees with these changes I will update the remaining database dialects/unit tests to include the |
No worries, same here!
Looks good to me! @Oreilles thoughts? |
Looks good! |
@Oreilles Agreed! But parsing arrays was still not working because postgres parses the default value if it is an array. A value declared like this:
will look like the following in the
And so, to account arrays I added an extra case to the parsing logic (code here). It feels a bit naive considering that any |
Hi guys, I hate leaving unfinished businesses behind, so I gave another round to this PR. With the latest changes:
For now, I think this is as far as this PR will go. A more complete version will probably require considerate changes to the code. Any questions or additional fixes that are vital to merge this PR, please let me know 👍 |
|
||
let [value, cast] = type.split('::'); | ||
let [value, cast] = column_default.split('::'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the value contains "::", i think you must search the last "::"
This PR will add:
default_value_raw
to the types/column.ts that will contain the default raw value inspected from schema definitions;New types parsed:
Caveat
The module pg-types uses the data type oid to find the appropriate parser for the column type. In contrast, knex-schema-inspector uses
information_schema.data_type
. To bridge the pg-types approach to the knex-schema-inspector, this PR uses this map that may require to be updated in the future.Tasks
default_raw_value
default_value_raw
;pg-types
to support pg native data types;Closes #72