mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-27 19:02:03 +08:00
New provider and models API and CLI (#13865)
### What problem does this PR solve? As title. ### Type of change - [x] New Feature (non-breaking change which adds functionality) - [x] Refactoring --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@@ -166,8 +166,10 @@ func (p *Parser) parseAdminListCommand() (*Command, error) {
|
||||
return p.parseAdminListModelProviders()
|
||||
case TokenDefault:
|
||||
return p.parseAdminListDefaultModels()
|
||||
case TokenPool:
|
||||
return p.parseCommonListPoolModels()
|
||||
case TokenAvailable:
|
||||
return p.parseCommonListProviders()
|
||||
case TokenModels:
|
||||
return p.parseListModelsOfProvider()
|
||||
case TokenChats:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
@@ -273,31 +275,38 @@ func (p *Parser) parseAdminListDefaultModels() (*Command, error) {
|
||||
return NewCommand("list_user_default_models"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseCommonListPoolModels() (*Command, error) {
|
||||
p.nextToken() // consume POOL
|
||||
if p.curToken.Type == TokenProviders {
|
||||
return NewCommand("list_pool_providers"), nil
|
||||
} else if p.curToken.Type == TokenModels {
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenFrom {
|
||||
return nil, fmt.Errorf("expected FROM")
|
||||
}
|
||||
p.nextToken()
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := NewCommand("list_pool_models")
|
||||
cmd.Params["provider_name"] = providerName
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("expected PROVIDERS or MODELS")
|
||||
func (p *Parser) parseListModelsOfProvider() (*Command, error) {
|
||||
if p.curToken.Type != TokenModels {
|
||||
return nil, fmt.Errorf("expected MODELS")
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenFrom {
|
||||
return nil, fmt.Errorf("expected FROM")
|
||||
}
|
||||
p.nextToken()
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := NewCommand("list_provider_models")
|
||||
cmd.Params["provider_name"] = providerName
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseCommonListProviders() (*Command, error) {
|
||||
p.nextToken() // consume AVAILABLE
|
||||
|
||||
if p.curToken.Type != TokenProviders {
|
||||
return nil, fmt.Errorf("expected PROVIDERS")
|
||||
}
|
||||
|
||||
return NewCommand("list_available_providers"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseCommonShowPoolModel() (*Command, error) {
|
||||
@@ -409,8 +418,10 @@ func (p *Parser) parseAdminShowCommand() (*Command, error) {
|
||||
return p.parseShowVariable()
|
||||
case TokenService:
|
||||
return p.parseShowService()
|
||||
case TokenPool:
|
||||
return p.parseCommonShowPoolModel()
|
||||
case TokenProvider:
|
||||
return p.parseShowProvider()
|
||||
case TokenModel:
|
||||
return p.parseShowModel()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
|
||||
@@ -1006,15 +1006,17 @@ Commands (User Mode):
|
||||
LIST MODEL PROVIDERS; - List model providers
|
||||
LIST DEFAULT MODELS; - List default models
|
||||
LIST TOKENS; - List API tokens
|
||||
LIST PROVIDERS; - List available LLM providers
|
||||
CREATE TOKEN; - Create new API token
|
||||
CREATE PROVIDER 'name'; - Create a provider without API key
|
||||
CREATE PROVIDER 'name' 'api_key'; - Create a provider with API key
|
||||
DROP TOKEN 'token_value'; - Delete an API token
|
||||
DROP PROVIDER 'name'; - Delete a provider
|
||||
SET TOKEN 'token_value'; - Set and validate API token
|
||||
SHOW TOKEN; - Show current API token
|
||||
SHOW PROVIDER 'name'; - Show provider details
|
||||
UNSET TOKEN; - Remove current API token
|
||||
CREATE INDEX FOR DATASET 'name' VECTOR_SIZE N; - Create index for dataset
|
||||
DROP INDEX FOR DATASET 'name'; - Drop index for dataset
|
||||
CREATE INDEX DOC_META; - Create doc meta index
|
||||
DROP INDEX DOC_META; - Drop doc meta index
|
||||
ALTER PROVIDER 'name' NAME 'new_name'; - Rename a provider
|
||||
|
||||
Context Engine Commands (no quotes):
|
||||
ls [path] - List resources
|
||||
|
||||
@@ -152,14 +152,14 @@ func (c *RAGFlowClient) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.ListAdminTokens(cmd)
|
||||
case "drop_token":
|
||||
return c.DropAdminToken(cmd)
|
||||
case "list_pool_providers":
|
||||
return c.ListPoolProviders(cmd)
|
||||
case "show_pool_provider":
|
||||
return c.ShowPoolProvider(cmd)
|
||||
case "list_pool_models":
|
||||
return c.ListPoolModels(cmd)
|
||||
case "show_pool_model":
|
||||
return c.ShowPoolModel(cmd)
|
||||
case "list_available_providers":
|
||||
return c.ListAvailableProviders(cmd)
|
||||
case "show_provider":
|
||||
return c.ShowProvider(cmd)
|
||||
case "list_provider_models":
|
||||
return c.ListModels(cmd)
|
||||
case "show_model":
|
||||
return c.ShowModel(cmd)
|
||||
// TODO: Implement other commands
|
||||
default:
|
||||
return nil, fmt.Errorf("command '%s' would be executed with API", cmd.Type)
|
||||
@@ -204,13 +204,20 @@ func (c *RAGFlowClient) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
case "drop_doc_meta_index":
|
||||
return c.DropDocMetaIndex(cmd)
|
||||
case "list_pool_providers":
|
||||
return c.ListPoolProviders(cmd)
|
||||
case "show_pool_provider":
|
||||
return c.ShowPoolProvider(cmd)
|
||||
case "list_pool_models":
|
||||
return c.ListPoolModels(cmd)
|
||||
case "show_pool_model":
|
||||
return c.ShowPoolModel(cmd)
|
||||
return c.ListAvailableProviders(cmd)
|
||||
case "show_provider":
|
||||
return c.ShowProvider(cmd)
|
||||
case "list_provider_models":
|
||||
return c.ListModels(cmd)
|
||||
case "show_model":
|
||||
return c.ShowModel(cmd)
|
||||
// Provider commands
|
||||
case "create_provider":
|
||||
return c.CreateProvider(cmd)
|
||||
case "list_providers":
|
||||
return c.ListProviders(cmd)
|
||||
case "drop_provider":
|
||||
return c.DropProvider(cmd)
|
||||
// ContextEngine commands
|
||||
case "ce_ls":
|
||||
return c.CEList(cmd)
|
||||
|
||||
@@ -237,13 +237,13 @@ func (c *RAGFlowClient) Logout() (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListPoolProviders(cmd *Command) (ResponseIf, error) {
|
||||
func (c *RAGFlowClient) ListAvailableProviders(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
var endPoint string
|
||||
if c.ServerType == "admin" {
|
||||
endPoint = fmt.Sprintf("/admin/providers")
|
||||
endPoint = fmt.Sprintf("/admin/providers?available=true")
|
||||
} else {
|
||||
endPoint = fmt.Sprintf("/providers")
|
||||
endPoint = fmt.Sprintf("/providers?available=true")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, true, "web", nil, nil)
|
||||
@@ -267,7 +267,7 @@ func (c *RAGFlowClient) ListPoolProviders(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ShowPoolProvider(cmd *Command) (ResponseIf, error) {
|
||||
func (c *RAGFlowClient) ShowProvider(cmd *Command) (ResponseIf, error) {
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider_name not provided")
|
||||
@@ -301,7 +301,7 @@ func (c *RAGFlowClient) ShowPoolProvider(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListPoolModels(cmd *Command) (ResponseIf, error) {
|
||||
func (c *RAGFlowClient) ListModels(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
@@ -336,7 +336,7 @@ func (c *RAGFlowClient) ListPoolModels(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ShowPoolModel(cmd *Command) (ResponseIf, error) {
|
||||
func (c *RAGFlowClient) ShowModel(cmd *Command) (ResponseIf, error) {
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider_name not provided")
|
||||
|
||||
@@ -301,8 +301,10 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenVectorSize, Value: ident}
|
||||
case "DOC_META":
|
||||
return Token{Type: TokenDocMeta, Value: ident}
|
||||
case "POOL":
|
||||
return Token{Type: TokenPool, Value: ident}
|
||||
case "AVAILABLE":
|
||||
return Token{Type: TokenAvailable, Value: ident}
|
||||
case "NAME":
|
||||
return Token{Type: TokenName, Value: ident}
|
||||
default:
|
||||
return Token{Type: TokenIdentifier, Value: ident}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ const (
|
||||
TokenKey
|
||||
TokenKeys
|
||||
TokenGenerate
|
||||
TokenPool
|
||||
TokenAvailable
|
||||
TokenModel
|
||||
TokenModels
|
||||
TokenProvider
|
||||
@@ -103,6 +103,7 @@ const (
|
||||
TokenIndex
|
||||
TokenVectorSize
|
||||
TokenDocMeta
|
||||
TokenName // For ALTER PROVIDER <name> NAME <new_name>
|
||||
|
||||
// Literals
|
||||
TokenIdentifier
|
||||
|
||||
@@ -751,6 +751,119 @@ func (c *RAGFlowClient) DropDocMetaIndex(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// CreateProvider creates a new model provider
|
||||
// CREATE PROVIDER <name>
|
||||
// CREATE PROVIDER <name> <api_key>
|
||||
func (c *RAGFlowClient) CreateProvider(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "user" {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider name not provided")
|
||||
}
|
||||
|
||||
// Get optional api_key
|
||||
apiKey, _ := cmd.Params["api_key"].(string)
|
||||
|
||||
// Build payload
|
||||
payload := map[string]interface{}{
|
||||
"llm_factory": providerName,
|
||||
"api_key": apiKey,
|
||||
"verify": apiKey != "", // Only verify if api_key is provided
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", "/llm/set_api_key", true, "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create provider: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to create provider: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("create provider failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListProviders lists all providers
|
||||
// LIST PROVIDERS
|
||||
func (c *RAGFlowClient) ListProviders(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "user" {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/llm/factories", true, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list providers: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list providers: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list providers failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// DropProvider deletes a provider
|
||||
// DROP PROVIDER <name>
|
||||
func (c *RAGFlowClient) DropProvider(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "user" {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider name not provided")
|
||||
}
|
||||
|
||||
// Build payload
|
||||
payload := map[string]interface{}{
|
||||
"llm_factory": providerName,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", "/llm/factory", true, "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop provider: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to drop provider: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("drop provider failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// Context related commands
|
||||
|
||||
// CEList handles the ls command - lists nodes using Context Engine
|
||||
|
||||
@@ -151,10 +151,14 @@ func (p *Parser) parseListCommand() (*Command, error) {
|
||||
return p.parseListTokens()
|
||||
case TokenModel:
|
||||
return p.parseListModelProviders()
|
||||
case TokenModels:
|
||||
return p.parseListModelsOfProvider()
|
||||
case TokenProviders:
|
||||
return p.parseListProviders()
|
||||
case TokenDefault:
|
||||
return p.parseListDefaultModels()
|
||||
case TokenPool:
|
||||
return p.parseCommonListPoolModels()
|
||||
case TokenAvailable:
|
||||
return p.parseCommonListProviders()
|
||||
case TokenChats:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
@@ -259,6 +263,16 @@ func (p *Parser) parseListModelProviders() (*Command, error) {
|
||||
return NewCommand("list_user_model_providers"), nil
|
||||
}
|
||||
|
||||
// parseListProviders parses LIST PROVIDERS command
|
||||
func (p *Parser) parseListProviders() (*Command, error) {
|
||||
p.nextToken() // consume PROVIDERS
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("list_providers"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseListDefaultModels() (*Command, error) {
|
||||
p.nextToken() // consume DEFAULT
|
||||
if p.curToken.Type != TokenModels {
|
||||
@@ -336,8 +350,10 @@ func (p *Parser) parseShowCommand() (*Command, error) {
|
||||
return p.parseShowVariable()
|
||||
case TokenService:
|
||||
return p.parseShowService()
|
||||
case TokenPool:
|
||||
return p.parseCommonShowPoolModel()
|
||||
case TokenProvider:
|
||||
return p.parseShowProvider()
|
||||
case TokenModel:
|
||||
return p.parseShowModel()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -433,6 +449,56 @@ func (p *Parser) parseShowService() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowModel() (*Command, error) {
|
||||
p.nextToken() // consume model
|
||||
|
||||
modelName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected model name: %w", err)
|
||||
}
|
||||
|
||||
cmd := NewCommand("show_model")
|
||||
cmd.Params["model_name"] = modelName
|
||||
|
||||
p.nextToken() // consume model_name
|
||||
|
||||
if p.curToken.Type != TokenFrom {
|
||||
return nil, fmt.Errorf("expected FROM")
|
||||
}
|
||||
p.nextToken() // consume from
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected provider name: %w", err)
|
||||
}
|
||||
cmd.Params["provider_name"] = providerName
|
||||
p.nextToken() // consume provider name
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseShowProvider parses SHOW PROVIDER <name> command
|
||||
func (p *Parser) parseShowProvider() (*Command, error) {
|
||||
p.nextToken() // consume PROVIDER
|
||||
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected provider name: %w", err)
|
||||
}
|
||||
|
||||
cmd := NewCommand("show_provider")
|
||||
cmd.Params["provider_name"] = providerName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseCreateCommand() (*Command, error) {
|
||||
p.nextToken() // consume CREATE
|
||||
|
||||
@@ -443,6 +509,8 @@ func (p *Parser) parseCreateCommand() (*Command, error) {
|
||||
return p.parseCreateRole()
|
||||
case TokenModel:
|
||||
return p.parseCreateModelProvider()
|
||||
case TokenProvider:
|
||||
return p.parseCreateProvider()
|
||||
case TokenDataset:
|
||||
return p.parseCreateDataset()
|
||||
case TokenChat:
|
||||
@@ -606,6 +674,39 @@ func (p *Parser) parseCreateModelProvider() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseCreateProvider parses CREATE PROVIDER commands
|
||||
// CREATE PROVIDER <name>
|
||||
// CREATE PROVIDER <name> <api_key>
|
||||
func (p *Parser) parseCreateProvider() (*Command, error) {
|
||||
p.nextToken() // consume PROVIDER
|
||||
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected provider name: %w", err)
|
||||
}
|
||||
|
||||
cmd := NewCommand("create_provider")
|
||||
cmd.Params["provider_name"] = providerName
|
||||
|
||||
p.nextToken()
|
||||
|
||||
// Check if api_key is provided (optional)
|
||||
if p.curToken.Type == TokenQuotedString {
|
||||
apiKey, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected api key: %w", err)
|
||||
}
|
||||
cmd.Params["api_key"] = apiKey
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseCreateDataset() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
datasetName, err := p.parseQuotedString()
|
||||
@@ -688,6 +789,8 @@ func (p *Parser) parseDropCommand() (*Command, error) {
|
||||
return p.parseDropRole()
|
||||
case TokenModel:
|
||||
return p.parseDropModelProvider()
|
||||
case TokenProvider:
|
||||
return p.parseDropProvider()
|
||||
case TokenDataset:
|
||||
return p.parseDropDataset()
|
||||
case TokenChat:
|
||||
@@ -831,6 +934,26 @@ func (p *Parser) parseDropModelProvider() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseDropProvider parses DROP PROVIDER <name> command
|
||||
func (p *Parser) parseDropProvider() (*Command, error) {
|
||||
p.nextToken() // consume PROVIDER
|
||||
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected provider name: %w", err)
|
||||
}
|
||||
|
||||
cmd := NewCommand("drop_provider")
|
||||
cmd.Params["provider_name"] = providerName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseDropDataset() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
datasetName, err := p.parseQuotedString()
|
||||
@@ -875,6 +998,8 @@ func (p *Parser) parseAlterCommand() (*Command, error) {
|
||||
return p.parseAlterUser()
|
||||
case TokenRole:
|
||||
return p.parseAlterRole()
|
||||
case TokenProvider:
|
||||
return p.parseAlterProvider()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ALTER target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1004,6 +1129,38 @@ func (p *Parser) parseAlterRole() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseAlterProvider parses ALTER PROVIDER <name> NAME <new_name> command
|
||||
func (p *Parser) parseAlterProvider() (*Command, error) {
|
||||
p.nextToken() // consume PROVIDER
|
||||
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected provider name: %w", err)
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenName {
|
||||
return nil, fmt.Errorf("expected NAME")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
newName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected new provider name: %w", err)
|
||||
}
|
||||
|
||||
cmd := NewCommand("alter_provider")
|
||||
cmd.Params["provider_name"] = providerName
|
||||
cmd.Params["new_name"] = newName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseGrantCommand() (*Command, error) {
|
||||
p.nextToken() // consume GRANT
|
||||
|
||||
|
||||
Reference in New Issue
Block a user