Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ type CreateQuery struct {
CreateDatabase bool `json:"create_database,omitempty"`
CreateFunction bool `json:"create_function,omitempty"`
CreateUser bool `json:"create_user,omitempty"`
AlterUser bool `json:"alter_user,omitempty"`
HasAuthenticationData bool `json:"has_authentication_data,omitempty"`
CreateDictionary bool `json:"create_dictionary,omitempty"`
DictionaryAttrs []*DictionaryAttributeDeclaration `json:"dictionary_attrs,omitempty"`
DictionaryDef *DictionaryDefinition `json:"dictionary_def,omitempty"`
Expand Down Expand Up @@ -659,6 +661,7 @@ const (
ShowCreateDB ShowType = "CREATE_DATABASE"
ShowCreateDictionary ShowType = "CREATE_DICTIONARY"
ShowCreateView ShowType = "CREATE_VIEW"
ShowCreateUser ShowType = "CREATE_USER"
ShowColumns ShowType = "COLUMNS"
ShowDictionaries ShowType = "DICTIONARIES"
ShowFunctions ShowType = "FUNCTIONS"
Expand Down
15 changes: 13 additions & 2 deletions internal/explain/statements.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,13 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string,
}
return
}
if n.CreateUser {
fmt.Fprintf(sb, "%sCreateUserQuery\n", indent)
if n.CreateUser || n.AlterUser {
if n.HasAuthenticationData {
fmt.Fprintf(sb, "%sCreateUserQuery (children 1)\n", indent)
fmt.Fprintf(sb, "%s AuthenticationData\n", indent)
} else {
fmt.Fprintf(sb, "%sCreateUserQuery\n", indent)
}
return
}
if n.CreateDictionary {
Expand Down Expand Up @@ -551,6 +556,12 @@ func explainShowQuery(sb *strings.Builder, n *ast.ShowQuery, indent string) {
return
}

// SHOW CREATE USER has special output format
if n.ShowType == ast.ShowCreateUser {
fmt.Fprintf(sb, "%sSHOW CREATE USER query\n", indent)
return
}

// SHOW TABLES FROM database - include database as child
if n.ShowType == ast.ShowTables && n.From != "" {
fmt.Fprintf(sb, "%sShowTables (children 1)\n", indent)
Expand Down
45 changes: 45 additions & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ func (p *Parser) parseStatement() ast.Statement {
case token.DROP:
return p.parseDrop()
case token.ALTER:
// Check for ALTER USER
if p.peekIs(token.USER) {
return p.parseAlterUser()
}
return p.parseAlter()
case token.TRUNCATE:
return p.parseTruncate()
Expand Down Expand Up @@ -1809,10 +1813,44 @@ func (p *Parser) parseCreateUser(create *ast.CreateQuery) {
// Parse user name
create.UserName = p.parseIdentifierName()

// Look for authentication data (NOT IDENTIFIED or IDENTIFIED)
// Scan through tokens looking for these keywords
for !p.currentIs(token.EOF) && !p.currentIs(token.SEMICOLON) {
// Check for NOT IDENTIFIED
if p.currentIs(token.NOT) {
p.nextToken()
if p.currentIs(token.IDENT) && strings.ToUpper(p.current.Value) == "IDENTIFIED" {
create.HasAuthenticationData = true
}
continue
}
// Check for IDENTIFIED (without NOT)
if p.currentIs(token.IDENT) && strings.ToUpper(p.current.Value) == "IDENTIFIED" {
create.HasAuthenticationData = true
}
p.nextToken()
}
}

func (p *Parser) parseAlterUser() *ast.CreateQuery {
create := &ast.CreateQuery{
Position: p.current.Pos,
CreateUser: true,
AlterUser: true,
}

p.nextToken() // skip ALTER
p.nextToken() // skip USER

// Parse user name
create.UserName = p.parseIdentifierName()

// Skip the rest of the user definition (complex syntax)
for !p.currentIs(token.EOF) && !p.currentIs(token.SEMICOLON) {
p.nextToken()
}

return create
}

func (p *Parser) parseCreateGeneric(create *ast.CreateQuery) {
Expand Down Expand Up @@ -3309,6 +3347,13 @@ func (p *Parser) parseShow() ast.Statement {
} else if p.currentIs(token.IDENT) && strings.ToUpper(p.current.Value) == "VIEW" {
show.ShowType = ast.ShowCreateView
p.nextToken()
} else if p.currentIs(token.USER) {
show.ShowType = ast.ShowCreateUser
p.nextToken()
// Skip user name and host pattern - they don't affect explain output
for !p.currentIs(token.EOF) && !p.currentIs(token.SEMICOLON) {
p.nextToken()
}
} else {
show.ShowType = ast.ShowCreate
// Handle SHOW CREATE TABLE, etc.
Expand Down
37 changes: 1 addition & 36 deletions parser/testdata/01075_allowed_client_hosts/metadata.json
Original file line number Diff line number Diff line change
@@ -1,36 +1 @@
{
"explain_todo": {
"stmt10": true,
"stmt11": true,
"stmt12": true,
"stmt13": true,
"stmt14": true,
"stmt15": true,
"stmt16": true,
"stmt17": true,
"stmt18": true,
"stmt19": true,
"stmt20": true,
"stmt21": true,
"stmt22": true,
"stmt23": true,
"stmt24": true,
"stmt25": true,
"stmt26": true,
"stmt27": true,
"stmt28": true,
"stmt29": true,
"stmt3": true,
"stmt32": true,
"stmt33": true,
"stmt34": true,
"stmt35": true,
"stmt36": true,
"stmt4": true,
"stmt5": true,
"stmt6": true,
"stmt7": true,
"stmt8": true,
"stmt9": true
}
}
{}
103 changes: 1 addition & 102 deletions parser/testdata/01292_create_user/metadata.json
Original file line number Diff line number Diff line change
@@ -1,136 +1,35 @@
{
"explain_todo": {
"stmt100": true,
"stmt101": true,
"stmt102": true,
"stmt103": true,
"stmt104": true,
"stmt105": true,
"stmt106": true,
"stmt107": true,
"stmt108": true,
"stmt109": true,
"stmt11": true,
"stmt110": true,
"stmt111": true,
"stmt112": true,
"stmt12": true,
"stmt124": true,
"stmt125": true,
"stmt126": true,
"stmt127": true,
"stmt128": true,
"stmt129": true,
"stmt13": true,
"stmt130": true,
"stmt131": true,
"stmt132": true,
"stmt133": true,
"stmt134": true,
"stmt135": true,
"stmt136": true,
"stmt137": true,
"stmt138": true,
"stmt14": true,
"stmt141": true,
"stmt148": true,
"stmt149": true,
"stmt150": true,
"stmt151": true,
"stmt152": true,
"stmt153": true,
"stmt155": true,
"stmt156": true,
"stmt157": true,
"stmt158": true,
"stmt159": true,
"stmt16": true,
"stmt160": true,
"stmt161": true,
"stmt162": true,
"stmt163": true,
"stmt164": true,
"stmt165": true,
"stmt166": true,
"stmt169": true,
"stmt17": true,
"stmt170": true,
"stmt171": true,
"stmt172": true,
"stmt177": true,
"stmt18": true,
"stmt182": true,
"stmt186": true,
"stmt189": true,
"stmt196": true,
"stmt197": true,
"stmt198": true,
"stmt200": true,
"stmt201": true,
"stmt205": true,
"stmt206": true,
"stmt207": true,
"stmt208": true,
"stmt21": true,
"stmt219": true,
"stmt22": true,
"stmt221": true,
"stmt23": true,
"stmt234": true,
"stmt235": true,
"stmt236": true,
"stmt239": true,
"stmt24": true,
"stmt25": true,
"stmt26": true,
"stmt27": true,
"stmt28": true,
"stmt29": true,
"stmt30": true,
"stmt31": true,
"stmt32": true,
"stmt33": true,
"stmt34": true,
"stmt35": true,
"stmt36": true,
"stmt37": true,
"stmt38": true,
"stmt39": true,
"stmt40": true,
"stmt41": true,
"stmt42": true,
"stmt43": true,
"stmt44": true,
"stmt45": true,
"stmt46": true,
"stmt47": true,
"stmt48": true,
"stmt6": true,
"stmt67": true,
"stmt68": true,
"stmt69": true,
"stmt70": true,
"stmt71": true,
"stmt72": true,
"stmt73": true,
"stmt74": true,
"stmt75": true,
"stmt76": true,
"stmt77": true,
"stmt78": true,
"stmt79": true,
"stmt80": true,
"stmt81": true,
"stmt82": true,
"stmt83": true,
"stmt84": true,
"stmt85": true,
"stmt86": true,
"stmt87": true,
"stmt88": true,
"stmt89": true,
"stmt9": true,
"stmt90": true,
"stmt99": true
"stmt6": true
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"explain_todo": {
"stmt2": true,
"stmt3": true,
"stmt5": true
}
}
1 change: 0 additions & 1 deletion parser/testdata/01999_grant_with_replace/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"explain_todo": {
"stmt26": true,
"stmt27": true,
"stmt3": true,
"stmt47": true,
"stmt48": true,
"stmt52": true,
Expand Down
3 changes: 1 addition & 2 deletions parser/testdata/02867_create_user_ssh/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"stmt2": true,
"stmt3": true,
"stmt4": true,
"stmt5": true,
"stmt6": true
"stmt5": true
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"explain_todo": {
"stmt1": true,
"stmt2": true,
"stmt4": true,
"stmt5": true
"stmt4": true
}
}