Skip to content
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

Support the PostgreSQL domain #532

Merged
merged 11 commits into from
Feb 24, 2025
Merged

Conversation

Leo-XM-Zeng
Copy link
Contributor

@Leo-XM-Zeng Leo-XM-Zeng commented Jan 14, 2025

Domain types are basically user defined aliases of existing types. This starts supporting columns of such domain types pg_duckdb. One interesting thing is that domain types can also contain constraints, e.g. "an int that is less than 10". This doesn't really matter for reading them though, their actual representation is still always the same as the underlying type. It also doesn't matter when doing operations on them, because Postgres already changes a domain type to its underlying representation automatically. So any constraints on the domain don't apply to a result of an operation (e.g. addition).

Fixes #514

@JelteF JelteF added this to the 0.4.0 milestone Feb 4, 2025
@Leo-XM-Zeng
Copy link
Contributor Author

I have simply merged and updated the project code. Could you please review it for me again? I have thought about some parts and made some adjustments. Although there might be some places where I didn't follow your way of adjustment completely.

Copy link
Collaborator

@JelteF JelteF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for continuing to update this. Left some final comments. After that this can be merged.

src/pg/types.cpp Outdated
Comment on lines 35 to 50
Oid
GetBaseDuckColumnType(Oid attribute_typoid) {
std::lock_guard<std::recursive_mutex> lock(pgduckdb::GlobalProcessLock::GetLock());
Oid typoid = attribute_typoid;
if (get_typtype(attribute_typoid) == TYPTYPE_DOMAIN) {
/* It is a domain type that needs to be reduced to its base type */
typoid = getBaseType(attribute_typoid);
} else if (type_is_array(attribute_typoid)) {
Oid eltoid = get_base_element_type(attribute_typoid);
if (OidIsValid(eltoid) && get_typtype(eltoid) == TYPTYPE_DOMAIN) {
/* When the member type of an array is domain, you need to build a base array type */
typoid = get_array_type(getBaseType(eltoid));
}
}
return typoid;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of these functions can throw Postgres errors (like get_typtype and getBaseType). They all need to be wrapped in PostgresFunctionGuard. It's probably easiest to create a small wrapper function like this:

Suggested change
Oid
GetBaseDuckColumnType(Oid attribute_typoid) {
std::lock_guard<std::recursive_mutex> lock(pgduckdb::GlobalProcessLock::GetLock());
Oid typoid = attribute_typoid;
if (get_typtype(attribute_typoid) == TYPTYPE_DOMAIN) {
/* It is a domain type that needs to be reduced to its base type */
typoid = getBaseType(attribute_typoid);
} else if (type_is_array(attribute_typoid)) {
Oid eltoid = get_base_element_type(attribute_typoid);
if (OidIsValid(eltoid) && get_typtype(eltoid) == TYPTYPE_DOMAIN) {
/* When the member type of an array is domain, you need to build a base array type */
typoid = get_array_type(getBaseType(eltoid));
}
}
return typoid;
}
static Oid
GetBaseDuckColumnType_C(Oid attribute_typoid) {
std::lock_guard<std::recursive_mutex> lock(pgduckdb::GlobalProcessLock::GetLock());
Oid typoid = attribute_typoid;
if (get_typtype(attribute_typoid) == TYPTYPE_DOMAIN) {
/* It is a domain type that needs to be reduced to its base type */
typoid = getBaseType(attribute_typoid);
} else if (type_is_array(attribute_typoid)) {
Oid eltoid = get_base_element_type(attribute_typoid);
if (OidIsValid(eltoid) && get_typtype(eltoid) == TYPTYPE_DOMAIN) {
/* When the member type of an array is domain, you need to build a base array type */
typoid = get_array_type(getBaseType(eltoid));
}
}
return typoid;
}
Oid
GetBaseDuckColumnType(Oid attribute_type_oid) {
return PostgresFunctionGuard(GetBaseDuckColumnType_C, attribute_type_oid);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thank you very much for your guidance. I feel that the lock in the c function seems to have no effect at this time, so I try to remove it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agreed.

@JelteF JelteF merged commit 8cf199b into duckdb:main Feb 24, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unsupported Postgres domain type
2 participants