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 COMMENT ON TABLE statement #200

Merged
merged 3 commits into from Apr 3, 2019
Merged

Support COMMENT ON TABLE statement #200

merged 3 commits into from Apr 3, 2019

Conversation

ebyhr
Copy link
Member

@ebyhr ebyhr commented Feb 9, 2019

@martint
Copy link
Member

martint commented Feb 14, 2019

There's no equivalent functionality in the standard, but this syntax is fairly low risk with respect to future incompatibilities due to being a top-level statement that doesn't interact with anything else. While the syntax is not great (it's not consistent with every other operation on table metadata), it's similar to what Oracle and Postgres do, so let's stick with it.

Copy link
Member

@martint martint left a comment

Choose a reason for hiding this comment

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

Some initial comments

public void testCommentTable()
{
// Accumulo connector currently does not support comment on table
assertQueryFails("COMMENT ON TABLE orders IS 'hello'", "This connector does not support commenting tables");
Copy link
Member

Choose a reason for hiding this comment

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

... does not support table comments ...

@@ -0,0 +1,22 @@
+=============
COMMENT TABLE
Copy link
Member

Choose a reason for hiding this comment

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

I'd refer to this just as "COMMENT". The current implementation only supports tables, but we might extend it in the future to support other object types like Postgres does (https://www.postgresql.org/docs/9.1/sql-comment.html)

@Override
public String getName()
{
return "COMMENT TABLE";
Copy link
Member

Choose a reason for hiding this comment

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

Just "COMMENT"

* Check if identity is allowed to comment the specified table.
* @throws io.prestosql.spi.security.AccessDeniedException if not allowed
*/
void checkCanAddComment(TransactionId transactionId, Identity identity, QualifiedObjectName tableName);
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure we want or need a dedicated access check for this operation. It should, generally, fall under "does the user have permission to update the table definition?".

Copy link
Member

Choose a reason for hiding this comment

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

We don't have generic permissions like that. There are separate checks like checkCanAddColumns, checkCanDropColumn, checkCanRenameColumn, checkCanRenameTable, etc.

How about making this checkCanSetTableComment?

import static com.google.common.base.MoreObjects.toStringHelper;
import static java.util.Objects.requireNonNull;

public final class CommentTable
Copy link
Member

Choose a reason for hiding this comment

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

I'd make this a little more generic. I expect we'll be adding comments on other object types shortly after. It should be structured as

  • Comment
    • target: initially something that identifies a table, but eventually other types of entities, too. I'd make a new NamedObject that contains (type, name). Type can only be a table for now.
    • comment: a string

Copy link
Member Author

Choose a reason for hiding this comment

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

@martint My understanding is the suggestion means SqlBase.g4 also should be changed. Is it right?

Current:

    | COMMENT ON TABLE qualifiedName IS string                         #commentTable

New:

    | COMMENT ON commentObject qualifiedName IS string                 #comment
...
commentObject
    : TABLE          #commentTable
    ;

Copy link
Member

@electrum electrum Mar 2, 2019

Choose a reason for hiding this comment

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

No, the grammar is fine. Rather than introducing a literal object, we can add a Type enum like other AST nodes use. It can be refactored into object later if needed.

Copy link
Member Author

Choose a reason for hiding this comment

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

I see. Thank you for answering.

@martint martint assigned ebyhr and unassigned martint Feb 21, 2019
* Check if identity is allowed to comment the specified table.
* @throws io.prestosql.spi.security.AccessDeniedException if not allowed
*/
void checkCanAddComment(TransactionId transactionId, Identity identity, QualifiedObjectName tableName);
Copy link
Member

Choose a reason for hiding this comment

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

We don't have generic permissions like that. There are separate checks like checkCanAddColumns, checkCanDropColumn, checkCanRenameColumn, checkCanRenameTable, etc.

How about making this checkCanSetTableComment?

Description
-----------

Add a comment to an existing table.
Copy link
Member

Choose a reason for hiding this comment

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

This is not just "add", since this can update or remove an existing comment. How about

Set the comment for a table. The comment can be removed by setting the comment to ``NULL``.

Examples
--------

Add the comment ``master table`` to the ``users`` table::
Copy link
Member

Choose a reason for hiding this comment

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

Change the comment for the ``users`` table to be ``master table``::

/**
* Comments to the specified table
*/
default void commentTable(ConnectorSession session, ConnectorTableHandle tableHandle, String comment)
Copy link
Member

Choose a reason for hiding this comment

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

Let's name this setTableComment and also change String to be Optional<String>. This aligns with how comment is represented in ConnectorTableMetadata and allows a single call to add/update/remove.

*/
default void commentTable(ConnectorSession session, ConnectorTableHandle tableHandle, String comment)
{
throw new PrestoException(NOT_SUPPORTED, "This connector does not support commenting tables");
Copy link
Member

Choose a reason for hiding this comment

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

This connector does not support setting table comments

@ebyhr
Copy link
Member Author

ebyhr commented Mar 3, 2019

Changes:

  • Introduce enum for comment target object
  • Rename methods addComment* to setTableComment*
  • Use Optional<String> for comment body

public synchronized void commentTable(String databaseName, String tableName, Optional<String> comment)
{
alterTable(databaseName, tableName, oldTable -> {
return oldTable.withParameters(ImmutableMap.<String, String>builder()
Copy link
Member

Choose a reason for hiding this comment

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

This is a single expression, so return and {} are unnecessary.

org.apache.hadoop.hive.metastore.api.Table table = source.get();

Map<String, String> parameters = table.getParameters();
parameters.put(TABLE_COMMENT, comment.orElse(""));
Copy link
Member

Choose a reason for hiding this comment

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

If comment is Optional.empty(), the comment should be removed. Does the hive metastore support removing comments explicitly or does it consider an empty comment the same as not having a comment? What happens if after clearing the comment you run DESCRIBE <table>? Does it show COMMENT ''?

Copy link
Member Author

Choose a reason for hiding this comment

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

hive supports both empty comment and removing a comment (ALTER UNSET). Actually, I tryied to remove the comment when it is empty, but followed the hive behaviour. Which do you think is better?

hive> ALTER TABLE table1 SET TBLPROPERTIES ('comment' = '');
hive> desc formatted table1;
...
Table Parameters:	 	 
	comment             	                    
	last_modified_by    	root                
...
hive> ALTER TABLE table1 UNSET TBLPROPERTIES ('comment');
hive> desc formatted table1;
...
Table Parameters:	 	 
	last_modified_by    	root                
...

@martint
Copy link
Member

martint commented Mar 18, 2019

@ebyhr, can you squash the fixups into the corresponding commits? I'll do another review pass after that. Reassign to me when you've done it.

@ebyhr
Copy link
Member Author

ebyhr commented Mar 20, 2019

@martint Updated. Unfortunately, I don't have a permission to change the assignees.

@ebyhr
Copy link
Member Author

ebyhr commented Mar 20, 2019

I think this @electrum 's comment #200 (comment) requires SqlBase.g4 change like below. Please let me know if my understanding is wrong.

SqlBase.g4

COMMENT ON TABLE qualifiedName IS (string | NULL)                #commentTable

Current g4 shows mismatch error if I specify NULL.

presto:default> comment on table test_comment is null;
Query 20190320_160347_00001_s8r5r failed: line 1:34: mismatched input 'null'. Expecting: <string>
comment on table test_comment is null

@electrum
Copy link
Member

@ebyhr Yes, we'll need a minor change to the grammar to support NULL.

@ebyhr
Copy link
Member Author

ebyhr commented Mar 26, 2019

Thank you for answering. Let me update to accept NULL.

@ebyhr
Copy link
Member Author

ebyhr commented Mar 26, 2019

Updated. Current behavior:

  • COMMENT ON TABLE table IS '' sets empty comment
  • COMMENT ON TABLE table IS NULL removes comment

Copy link
Member

@martint martint left a comment

Choose a reason for hiding this comment

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

Just a few minor comments, but otherwise looks great! Once you rebased and address those issues, I'll merge it.

{
Session session = stateMachine.getSession();

if (statement.getType() == Comment.Type.TABLE) {
Copy link
Member

Choose a reason for hiding this comment

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

We should thrown a PrestoException with UNSUPPORTED code, otherwise.

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps, NOT_SUPPORTED is right? I couldn't find UNSUPPORTED code. Updated like this.

        else {
            throw new PrestoException(NOT_SUPPORTED, "Unsupported comment type: " + statement.getType());
        }

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that’s what I meant.

@Override
public void setTableComment(Session session, TableHandle tableHandle, Optional<String> comment)
{
ConnectorId connectorId = tableHandle.getConnectorId();
Copy link
Member

Choose a reason for hiding this comment

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

This has been changed to CatalogName in recent commits.

*
* @throws io.prestosql.spi.security.AccessDeniedException if not allowed
*/
default void checkCanCommentTable(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, SchemaTableName tableName)
Copy link
Member

Choose a reason for hiding this comment

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

Rename to checkCanSetTableComment for consistency with AccessControl.

@Override
public Node visitCommentTable(SqlBaseParser.CommentTableContext context)
{
String comment = context.string() != null ? ((StringLiteral) visit(context.string())).getValue() : null;
Copy link
Member

Choose a reason for hiding this comment

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

I find this form easier to read:

Optional<String> comment = Optional.empy();

if (context.string() != null) {
    comment = Optional.of(((StringLiteral) visit(context.string())).getValue())
}

return new Comment(...)

See how other visitXXX methods are implemented.

.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
comment.ifPresent(value -> parameters.put(TABLE_COMMENT, comment.get()));

table.setParameters(ImmutableMap.copyOf(parameters));
Copy link
Member

Choose a reason for hiding this comment

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

Why ImmutableMap.copyOf?

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed. It was debris during development.

@ebyhr
Copy link
Member Author

ebyhr commented Apr 3, 2019

@martint Thank you for your reviews. Rebased and applied the comments. Travis result is green.

*
* @throws AccessDeniedException if not allowed
*/
default void checkCanCommentTable(Identity identity, CatalogSchemaTableName table)
Copy link
Member

Choose a reason for hiding this comment

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

This should be checkCanSetTableComment

@ebyhr
Copy link
Member Author

ebyhr commented Apr 3, 2019

Sorry, overlooked that. Updated once again.

Copy link
Member

@martint martint left a comment

Choose a reason for hiding this comment

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

Looks great, thanks for your contribution!

@martint martint merged commit d813133 into trinodb:master Apr 3, 2019
@martint martint mentioned this pull request Apr 3, 2019
6 tasks
@electrum electrum added this to the 307 milestone Apr 4, 2019
@ebyhr ebyhr deleted the 4836 branch September 5, 2021 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

4 participants