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

Allow setting key/value in a metadata stored in the topology #5103

Merged

Conversation

kalfonso
Copy link
Contributor

@kalfonso kalfonso commented Aug 16, 2019

This PR allows setting key/value metadata in the topology leveraging "set" & "show" SQL statements.

Signed-off-by: Karel Alfonso Sague kalfonso@squareup.com

@kalfonso
Copy link
Contributor Author

@sougou @demmer @tirsen this is an initial cut of using "SET" statement to manage metadata values. Looking for feedback on this. I've commented in the PR about alternative options to manage topology backed metadata

@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch 6 times, most recently from cdfdfac to aa73834 Compare August 20, 2019 05:58
go/vt/vtgate/executor.go Outdated Show resolved Hide resolved
@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch from aa73834 to d4f59c0 Compare August 21, 2019 04:12
@kalfonso kalfonso changed the title WIP: Allow setting key/value in a metadata stored in the topology Allow setting key/value in a metadata stored in the topology Aug 21, 2019
@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch from d4f59c0 to 99eb8b7 Compare August 21, 2019 05:54
@kalfonso kalfonso marked this pull request as ready for review August 21, 2019 05:54
@kalfonso kalfonso requested a review from sougou as a code owner August 21, 2019 05:54

keyPattern := strings.Replace(regexp.QuoteMeta(keyFilter), "%", ".*", -1)
keyPattern = fmt.Sprintf("^%s$", keyPattern)
re := regexp.MustCompile(keyPattern)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd add a little comment at the end like // Can never 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.

Done

@@ -465,6 +465,11 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql
if k.Scope == sqlparser.GlobalStr {
return &sqltypes.Result{}, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "unsupported in set: global")
}

if k.Scope == sqlparser.VitessMetadataStr {
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a switch here now that you have >1 case?

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


show := "show vitess_metadata variables like 'app_keyspace%'"
result, err := executor.Execute(context.Background(), "TestExecute", session, show, nil)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is testify not used in Vitess? :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to be used only in one test go/vt/vtgate/engine/ordered_aggregate_test.go

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I just introduced it, and used it on the code I was working on at the time. You can and should definitely use it. :)

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. Used in the new tests

}
}

rows := make([][]sqltypes.Value, 0, 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd use len(metadata) as the capacity 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.

Done

t.Errorf("want migrations %v, result %v", wantqr, gotqr)
}

show = "show vitess_metadata variables"
Copy link
Collaborator

Choose a reason for hiding this comment

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

oh I didn't know the variables keyword. I assume this is "standard"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, wanted to keep same syntax

SHOW [GLOBAL | SESSION] VARIABLES
    [LIKE 'pattern' | WHERE expr]

https://dev.mysql.com/doc/refman/8.0/en/show-variables.html

@@ -680,6 +735,10 @@ func (e *Executor) handleShow(ctx context.Context, safeSession *SafeSession, sql

switch show.Type {
case sqlparser.KeywordString(sqlparser.COLLATION), sqlparser.KeywordString(sqlparser.VARIABLES):
if show.Scope == sqlparser.VitessMetadataStr {
return e.handleShowVitessMetadata(ctx, safeSession, destKeyspace, show.ShowTablesOpt)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You're still passing in the keyspace 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.

Removed

return &sqltypes.Result{}, nil
}

func (e *Executor) handleShowVitessMetadata(ctx context.Context, session *SafeSession, ksName string, opt *sqlparser.ShowTablesOpt) (*sqltypes.Result, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you're not using ksName?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch 3 times, most recently from a8b2f6c to de15fda Compare August 23, 2019 03:37
@@ -645,6 +649,63 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql
return &sqltypes.Result{}, nil
}

func (e *Executor) handleSetVitessMetadata(ctx context.Context, session *SafeSession, k sqlparser.SetKey, v interface{}) (*sqltypes.Result, error) {
//TODO(kalfonso): move to its own acl check and consolidate into an acl component that can handle multiple operations (vschema, metadata)
allowed := vschemaacl.Authorized(callerid.ImmediateCallerIDFromContext(ctx))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dweitzman I've made changes to use vschemaacl to authorize specific users to execute "set vitess_metadata" actions. This works for our current requirements but a separate PR will separate this into its own metadataacl definition. Trying to keeps this PR small

@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch from de15fda to a25abf2 Compare August 23, 2019 06:03
Copy link
Member

@demmer demmer left a comment

Choose a reason for hiding this comment

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

Overall this LGTM -- one minor comment but I'm happy with this syntax and approach.


keyPattern := strings.Replace(regexp.QuoteMeta(keyFilter), "%", ".*", -1)
keyPattern = fmt.Sprintf("^%s$", keyPattern)
re := regexp.MustCompile(keyPattern) // Can never fail
Copy link
Member

Choose a reason for hiding this comment

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

Are we 100% sure this is a compatible conversion from the LIKE syntax to regexp? Itt's fine for this use case but if there's a more robust and generic way to do this, we might get some mileage out of making it a common function in the Vitess code base.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I found this link with examples of the LIKE syntax: https://www.w3schools.com/sql/sql_like.asp

I we also need to support _.

I agree that extracting a "LIKE to regexp" converter into a separate file and a more shared place and then writing specific unit tests for that would be nice. I'm not sure we need to make that 100% compliant in this PR though. We can iterate on that once we have it in a central place with a nice suite of unit tests.

Copy link
Member

Choose a reason for hiding this comment

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

Yep -- totally agree 100%

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Extracted functionality to separate file with unit tests. Also supporting '_' character and escaping using ""

@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch 3 times, most recently from 40b7aef to 3bc0486 Compare August 26, 2019 13:55
Signed-off-by: Karel Alfonso Sague <kalfonso@squareup.com>
@kalfonso kalfonso force-pushed the kalfonso.190814-set-vitess-metadata branch from 3bc0486 to 453d54b Compare August 26, 2019 14:26
@tirsen tirsen merged commit ad6099c into vitessio:master Aug 28, 2019
Copy link
Contributor

@sougou sougou left a comment

Choose a reason for hiding this comment

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

We also need the ability to delete metadata. How about we treat an empty value as a delete?

@@ -84,6 +84,7 @@ const (
KeyspacesPath = "keyspaces"
ShardsPath = "shards"
TabletsPath = "tablets"
MetadataPath = "vitess_metadata"
Copy link
Contributor

Choose a reason for hiding this comment

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

Hope it's not too late. This should be just metadata, just like we didn't prefix the other paths with vitess_.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not too late. This is the path in zk right? Yes I agree this should be just metadata not vitess_metadata. The syntax should be SET @@vitess_metadata though just like all of our other SQL extensions. Right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. We don't want collisions in the variable name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed in this PR: #5141

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.

6 participants