[PostgreSQL] Improve parsing support for postgresql data types#73
[PostgreSQL] Improve parsing support for postgresql data types#73ntma wants to merge 10 commits intoknex:masterfrom
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_typeThen 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 👍 |
| if (column_type === 'ARRAY') return parseDefaultArray(column_default); | ||
|
|
||
| let [value, cast] = type.split('::'); | ||
| let [value, cast] = column_default.split('::'); |
There was a problem hiding this comment.
If the value contains "::", i think you must search the last "::"
This PR will add:
default_value_rawto 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_valuedefault_value_raw;pg-typesto support pg native data types;Closes #72