MCPcopy
hub / github.com/sqldef/sqldef / stripFuncResultTextCasts

Function stripFuncResultTextCasts

schema/normalize.go:608–682  ·  view source on GitHub ↗

stripFuncResultTextCasts removes text/character varying casts applied to function call results, e.g. current_setting(...)::text -> current_setting(...). PostgreSQL drops such casts when they are no-ops while storing policy expressions, so they must be ignored when comparing policies. This is only sa

(expr parser.Expr)

Source from the content-addressed store, hash-verified

606// safe for comparison; do not use the result to generate DDLs because casts on
607// functions returning non-text types are semantically meaningful.
608func stripFuncResultTextCasts(expr parser.Expr) parser.Expr {
609 if expr == nil {
610 return nil
611 }
612
613 switch e := expr.(type) {
614 case *parser.CastExpr:
615 inner := e.Expr
616 if paren, ok := inner.(*parser.ParenExpr); ok {
617 inner = paren.Expr
618 }
619 if _, isFunc := inner.(*parser.FuncExpr); isFunc && e.Type != nil {
620 typeStr := strings.ToLower(e.Type.Type)
621 if typeStr == "text" || typeStr == "character varying" {
622 return stripFuncResultTextCasts(inner)
623 }
624 }
625 return &parser.CastExpr{Expr: stripFuncResultTextCasts(e.Expr), Type: e.Type}
626 case *parser.ParenExpr:
627 return &parser.ParenExpr{Expr: stripFuncResultTextCasts(e.Expr)}
628 case *parser.NotExpr:
629 return &parser.NotExpr{Expr: stripFuncResultTextCasts(e.Expr)}
630 case *parser.AndExpr:
631 return &parser.AndExpr{Left: stripFuncResultTextCasts(e.Left), Right: stripFuncResultTextCasts(e.Right)}
632 case *parser.OrExpr:
633 return &parser.OrExpr{Left: stripFuncResultTextCasts(e.Left), Right: stripFuncResultTextCasts(e.Right)}
634 case *parser.ConcatExpr:
635 return &parser.ConcatExpr{Left: stripFuncResultTextCasts(e.Left), Right: stripFuncResultTextCasts(e.Right)}
636 case *parser.ComparisonExpr:
637 return &parser.ComparisonExpr{
638 Operator: e.Operator,
639 Left: stripFuncResultTextCasts(e.Left),
640 Right: stripFuncResultTextCasts(e.Right),
641 Escape: stripFuncResultTextCasts(e.Escape),
642 All: e.All,
643 Any: e.Any,
644 }
645 case *parser.BinaryExpr:
646 return &parser.BinaryExpr{
647 Operator: e.Operator,
648 Left: stripFuncResultTextCasts(e.Left),
649 Right: stripFuncResultTextCasts(e.Right),
650 }
651 case *parser.RangeCond:
652 return &parser.RangeCond{
653 Operator: e.Operator,
654 Left: stripFuncResultTextCasts(e.Left),
655 From: stripFuncResultTextCasts(e.From),
656 To: stripFuncResultTextCasts(e.To),
657 }
658 case *parser.IsExpr:
659 return &parser.IsExpr{Operator: e.Operator, Expr: stripFuncResultTextCasts(e.Expr)}
660 case *parser.FuncExpr:
661 exprs := make(parser.SelectExprs, len(e.Exprs))
662 for i, arg := range e.Exprs {
663 if aliased, ok := arg.(*parser.AliasedExpr); ok {
664 exprs[i] = &parser.AliasedExpr{Expr: stripFuncResultTextCasts(aliased.Expr), As: aliased.As}
665 } else {

Callers 2

areSamePolicyExprsMethod · 0.85

Calls

no outgoing calls

Tested by 1