github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/dfunctions/active_branch.go (about) 1 // Copyright 2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package dfunctions 16 17 import ( 18 "github.com/dolthub/go-mysql-server/sql" 19 "github.com/dolthub/go-mysql-server/sql/types" 20 21 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 22 "github.com/dolthub/dolt/go/libraries/doltcore/ref" 23 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" 24 ) 25 26 const ActiveBranchFuncName = "active_branch" 27 28 type ActiveBranchFunc struct { 29 } 30 31 // NewActiveBranchFunc creates a new ActiveBranchFunc expression. 32 func NewActiveBranchFunc() sql.Expression { 33 return &ActiveBranchFunc{} 34 } 35 36 // Eval implements the Expression interface. 37 func (ab *ActiveBranchFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 38 dbName := ctx.GetCurrentDatabase() 39 if dbName == "" { 40 // it is possible to have no current database in some contexts. 41 // When you first connect to a sql server, which has no databases, for example. 42 return nil, nil 43 } 44 45 dSess := dsess.DSessFromSess(ctx.Session) 46 47 ddb, ok := dSess.GetDoltDB(ctx, dbName) 48 if !ok { 49 // Not all databases are dolt databases. information_schema and mysql, for example. 50 return nil, nil 51 } 52 53 currentBranchRef, err := dSess.CWBHeadRef(ctx, dbName) 54 if err == doltdb.ErrOperationNotSupportedInDetachedHead { 55 // active_branch should return NULL if we're in detached head state 56 return nil, nil 57 } 58 if err != nil { 59 return nil, err 60 } 61 62 branches, err := ddb.GetBranches(ctx) 63 if err != nil { 64 return nil, err 65 } 66 67 for _, br := range branches { 68 if ref.EqualsCaseInsensitive(br, currentBranchRef) { 69 return br.GetPath(), nil 70 } 71 } 72 73 return nil, nil 74 } 75 76 // String implements the Stringer interface. 77 func (ab *ActiveBranchFunc) String() string { 78 return "ACTIVE_BRANCH()" 79 } 80 81 // IsNullable implements the Expression interface. 82 func (ab *ActiveBranchFunc) IsNullable() bool { 83 return false 84 } 85 86 // Resolved implements the Expression interface. 87 func (*ActiveBranchFunc) Resolved() bool { 88 return true 89 } 90 91 func (ab *ActiveBranchFunc) Type() sql.Type { 92 return types.Text 93 } 94 95 // Children implements the Expression interface. 96 func (*ActiveBranchFunc) Children() []sql.Expression { 97 return nil 98 } 99 100 // WithChildren implements the Expression interface. 101 func (ab *ActiveBranchFunc) WithChildren(children ...sql.Expression) (sql.Expression, error) { 102 if len(children) != 0 { 103 return nil, sql.ErrInvalidChildrenNumber.New(ab, len(children), 0) 104 } 105 return NewActiveBranchFunc(), nil 106 }