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

Implement pgtle.create_shell_type function to support shell type creation in pg_tle #205

Merged
merged 3 commits into from
Jun 13, 2023

Conversation

lyupan
Copy link
Contributor

@lyupan lyupan commented Jun 8, 2023

Description of changes:
Implement pgtle.create_shell_type/create_shell_type_if_not_exists function:

  1. They require two arguments: namespace and type name and can only be executed by pgtle_admin and superuser;
  2. Similar to https://github.com/aws/pg_tle/blob/main/docs/03_managing_extensions.md#pgtleregister_feature_if_not_existsproc-regproc-feature-pg_tle_features, create_shell_type_if_not_exists returns false if the type already exists while create_shell_type fails;
  3. Add a new pg_tle version 1.0.5 for the new datatype functions.

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.

…tion in pg_tle.

Co-authored-by: Jim Mlodgenski <jimmy76@gmail.com>
@@ -107,3 +107,26 @@ GRANT EXECUTE ON FUNCTION pgtle.install_extension_version_sql
version text,
ext text
) TO pgtle_admin;

Copy link
Contributor

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

Copy link
Contributor Author

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);
Copy link
Contributor

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

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, run pg_indent.

SELECT CURRENT_USER;
current_user
--------------
lyup
Copy link
Contributor

@formalLogicGirl formalLogicGirl Jun 9, 2023

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?

Copy link
Contributor Author

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"));
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

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

Copy link
Contributor Author

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
Comment on lines 95 to 105
address = TypeShellMake(typeName, typeNamespace, GetUserId());

/*
* Make effects of commands visible
*/
CommandCounterIncrement();

if (OidIsValid(address.objectId))
PG_RETURN_BOOL(true);

PG_RETURN_BOOL(false);
Copy link
Contributor

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.

Copy link
Contributor Author

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
Comment on lines 81 to 93
/*
* 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)));
}
Copy link
Contributor

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:

https://github.com/aws/pg_tle/blob/main/docs/03_managing_extensions.md#pgtleregister_feature_if_not_existsproc-regproc-feature-pg_tle_features

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

@jkatz jkatz self-requested a review June 9, 2023 15:53
Copy link
Contributor

@jkatz jkatz left a 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>
@lyupan
Copy link
Contributor Author

lyupan commented Jun 9, 2023

Thanks for the review! Made some updates based on the comments, please take another look.

Co-authored-by: Jim Mlodgenski <jimmy76@gmail.com>
Copy link
Contributor

@formalLogicGirl formalLogicGirl left a 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.

@formalLogicGirl formalLogicGirl merged commit 4ef921e into aws:main Jun 13, 2023
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.

4 participants