-
Notifications
You must be signed in to change notification settings - Fork 31
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
Implement pgtle.create_shell_type function to support shell type creation in pg_tle #205
Conversation
…tion in pg_tle. Co-authored-by: Jim Mlodgenski <jimmy76@gmail.com>
pg_tle--1.0.1--1.0.4.sql
Outdated
@@ -107,3 +107,26 @@ GRANT EXECUTE ON FUNCTION pgtle.install_extension_version_sql | |||
version text, | |||
ext text | |||
) TO pgtle_admin; | |||
|
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.
We should add a new minor version, instead of modifying 1.0.4
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.
Done. Added a new version 1.0.5
src/datatype.c
Outdated
tleadminoid = roleform->oid; | ||
ReleaseSysCache(tuple); | ||
|
||
CHECK_CAN_SET_ROLE(GetUserId(), tleadminoid); |
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.
nit : can we make the whitespace formatting consistent
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.
We may need a pgformatter
run -- it's available in the PostgreSQL repo.
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.
Done, run pg_indent
.
test/expected/pg_tle_datatype.out
Outdated
SELECT CURRENT_USER; | ||
current_user | ||
-------------- | ||
lyup |
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.
this will not match for other user aliases running the test and fail the test, right?
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.
Ah, this was a mistake. Fixed.
src/datatype.c
Outdated
Form_pg_authid roleform; | ||
Oid tleadminoid; | ||
|
||
tuple = SearchSysCache1(AUTHNAME, CStringGetDatum("pgtle_admin")); |
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.
pgtle_admin
should be defined in a constant. Unsure if it should be in constants.h
or tleextension.h
-- leaning towards tleextension.h
as it contains names specific to the TLE extension itself, though maybe those need to be moved to constants.h
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.
Defined a new constant PG_TLE_ADMIN
.
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.
I think you can simplify this by just calling get_role_oid
and don't have to re-implement
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.
Thanks for the suggestion! Fixed.
src/datatype.c
Outdated
address = TypeShellMake(typeName, typeNamespace, GetUserId()); | ||
|
||
/* | ||
* Make effects of commands visible | ||
*/ | ||
CommandCounterIncrement(); | ||
|
||
if (OidIsValid(address.objectId)) | ||
PG_RETURN_BOOL(true); | ||
|
||
PG_RETURN_BOOL(false); |
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.
I would opt to return an error if we're unable to create the shell type. That way, if this is in a transaction, it will fail.
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.
Yeah, that makes sense. Updated the code.
src/datatype.c
Outdated
/* | ||
* Look to see if type already exists | ||
*/ | ||
typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, | ||
CStringGetDatum(typeName), | ||
ObjectIdGetDatum(typeNamespace)); | ||
|
||
if (OidIsValid(typoid)) | ||
{ | ||
ereport(ERROR, | ||
(errcode(ERRCODE_DUPLICATE_OBJECT), | ||
errmsg("type \"%s\" already exists", typeName))); | ||
} |
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.
See comment below -- we could have a similar pattern to other functions, e.g. create_shell_type
which will error if the type already exists, and create_shell_type_if_not_exists
which will return false
if it exists. Example:
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.
Since we are mirroring the Postgres CREATE TYPE wouldn't it be good to keep the behavior similar? In Postgres, if the type already exists then an error is generated. I was thinking we want to do the same here.
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.
Add a new create_shell_type_if_not_exists function:
create_shell_type
now fails (report error) if the type already exists;
create_shell_type_if_not_exists
returns false if it exists.
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.
OOC when would a user call one over the other?
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.
Thats a great question. Its not clear to me that there is a very compelling use case for create_shell_type_if_not_exists
. In Postgres, there isn't a similar function. In pg_tle, by design, we want to prevent leaving behind a shell type when a custom base type created in pg_tle gets successfully dropped. So there is not supposed to be a scenario where a shell type is left behind, and if that were the case, it seems like an error message informing the user would be helpful. Shell types also can't be shared between different custom base types, so no expectation of the shell type having been already created for some other reason. So then it comes down to whether the user wants the create function to not error under any circumstance, in which case they should use create_shell_type_if_not_exists
. Is that a significant enough requirement that we need this function for?
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.
In pg_tle, by design, we want to prevent leaving behind a shell type when a custom base type created in pg_tle gets successfully dropped.
When a shell type is created, there's a field typisdefined
setting to false
indicating it's a shell type; when an actual type is defined, typisdefined
will be set to true
and the shell type becomes an actual type. When we drop the base type, there won't be any shell type left behind.
create_shell_type_if_not_exists
is similar to register_feature_if_not_exists
. They return false when the type/feature already exists, which may be useful for clients that don't want to get errors, for example if they don't want to fail the whole transaction.
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.
Not failing the transaction may be the significant use case that justifies the if_not_exists form of this function. Okay.
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.
Good start! Please see previous review for the requested changes / comments.
Description of the changes: 1. Add create_shell_type_if_not_exists funcion which returns false if the type already exists; create_shell_type fails if the type already exists. 2. Add a new version 1.0.5 for the datatype functions. Co-authored-by: Jim Mlodgenski <jimmy76@gmail.com>
Thanks for the review! Made some updates based on the comments, please take another look. |
Co-authored-by: Jim Mlodgenski <jimmy76@gmail.com>
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.
Looks mostly good to me. I think its good to merge and work on the next functions. We can revisit if there are any updates we still need. I think you've already addressed all the comments raised so far.
Description of changes:
Implement pgtle.create_shell_type/create_shell_type_if_not_exists function:
This is the first commit to support custom base types in pg_tle.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.