Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Feature/lpad rpad #522

Merged
merged 4 commits into from
Nov 5, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Code review fixes
Signed-off-by: Theo Despoudis <thdespou@hotmail.com>
  • Loading branch information
theodesp committed Nov 2, 2018
commit fb385973f595c51be298085ae9daf07b2d73927c
6 changes: 3 additions & 3 deletions sql/expression/function/logarithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
// logarithm function
var ErrInvalidArgumentForLogarithm = errors.NewKind("invalid argument value for logarithm: %v")

// MakeLogBase returns LogBase creator functions with a specific base.
func MakeLogBase(base float64) func(e sql.Expression) sql.Expression {
// NewLogBaseFunc returns LogBase creator function with a specific base.
func NewLogBaseFunc(base float64) func(e sql.Expression) sql.Expression {
return func(e sql.Expression) sql.Expression {
return NewLogBase(base, e)
}
Expand Down Expand Up @@ -90,7 +90,7 @@ type Log struct {
expression.BinaryExpression
}

// NewLn creates a new Log expression.
// NewLog creates a new Log expression.
func NewLog(args ...sql.Expression) (sql.Expression, error) {
argLen := len(args)
if argLen == 0 || argLen > 2 {
Expand Down
12 changes: 6 additions & 6 deletions sql/expression/function/logarithm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestLn(t *testing.T) {
}

for _, tt := range testCases {
f := MakeLogBase(math.E)(expression.NewGetField(0, tt.rowType, "", false))
f := NewLogBaseFunc(math.E)(expression.NewGetField(0, tt.rowType, "", false))
t.Run(tt.name, func(t *testing.T) {
t.Helper()
require := require.New(t)
Expand All @@ -48,7 +48,7 @@ func TestLn(t *testing.T) {
}

// Test Nil
f := MakeLogBase(math.E)(expression.NewGetField(0, sql.Float64, "", true))
f := NewLogBaseFunc(math.E)(expression.NewGetField(0, sql.Float64, "", true))
require := require.New(t)
result, err := f.Eval(sql.NewEmptyContext(), sql.NewRow(nil))
require.NoError(err)
Expand All @@ -75,7 +75,7 @@ func TestLog2(t *testing.T) {
}

for _, tt := range testCases {
f := MakeLogBase(float64(2))(expression.NewGetField(0, tt.rowType, "", false))
f := NewLogBaseFunc(float64(2))(expression.NewGetField(0, tt.rowType, "", false))
t.Run(tt.name, func(t *testing.T) {
t.Helper()
require := require.New(t)
Expand All @@ -91,7 +91,7 @@ func TestLog2(t *testing.T) {
}

// Test Nil
f := MakeLogBase(float64(2))(expression.NewGetField(0, sql.Float64, "", true))
f := NewLogBaseFunc(float64(2))(expression.NewGetField(0, sql.Float64, "", true))
require := require.New(t)
result, err := f.Eval(sql.NewEmptyContext(), sql.NewRow(nil))
require.NoError(err)
Expand All @@ -118,7 +118,7 @@ func TestLog10(t *testing.T) {
}

for _, tt := range testCases {
f := MakeLogBase(float64(10))(expression.NewGetField(0, tt.rowType, "", false))
f := NewLogBaseFunc(float64(10))(expression.NewGetField(0, tt.rowType, "", false))
t.Run(tt.name, func(t *testing.T) {
t.Helper()
require := require.New(t)
Expand All @@ -134,7 +134,7 @@ func TestLog10(t *testing.T) {
}

// Test Nil
f := MakeLogBase(float64(10))(expression.NewGetField(0, sql.Float64, "", true))
f := NewLogBaseFunc(float64(10))(expression.NewGetField(0, sql.Float64, "", true))
require := require.New(t)
result, err := f.Eval(sql.NewEmptyContext(), sql.NewRow(nil))
require.NoError(err)
Expand Down
10 changes: 5 additions & 5 deletions sql/expression/function/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ var Defaults = sql.Functions{
"json_extract": sql.FunctionN(NewJSONExtract),
"connection_id": sql.Function0(NewConnectionID),
"soundex": sql.Function1(NewSoundex),
"ln": sql.Function1(MakeLogBase(float64(math.E))),
"log2": sql.Function1(MakeLogBase(float64(2))),
"log10": sql.Function1(MakeLogBase(float64(10))),
"ln": sql.Function1(NewLogBaseFunc(float64(math.E))),
"log2": sql.Function1(NewLogBaseFunc(float64(2))),
"log10": sql.Function1(NewLogBaseFunc(float64(10))),
"log": sql.FunctionN(NewLog),
"rpad": sql.FunctionN(MakePadder(rightPadType)),
"lpad": sql.FunctionN(MakePadder(leftPadType)),
"rpad": sql.FunctionN(NewPadFunc(rPadType)),
"lpad": sql.FunctionN(NewPadFunc(lPadType)),
}
49 changes: 28 additions & 21 deletions sql/expression/function/rpad_lpad.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@ import (
"strings"

"gopkg.in/src-d/go-mysql-server.v0/sql"
"gopkg.in/src-d/go-errors.v1"
)

type padType int
var ErrDivisionByZero = errors.NewKind("division by zero")

type padType rune
const (
leftPadType = iota
rightPadType
lPadType padType = 'l'
rPadType padType = 'r'
)

// MakePadder returns a Pad creator functions with a specific padType.
func MakePadder(pType padType) func(e ...sql.Expression) (sql.Expression, error) {
// NewPadFunc returns a Pad creator function with a specific padType.
func NewPadFunc(pType padType) func(e ...sql.Expression) (sql.Expression, error) {
return func(e ...sql.Expression) (sql.Expression, error) {
return NewPad(pType, e...)
}
}

// NewLogBase creates a new LogBase expression.
// NewPad creates a new Pad expression.
func NewPad(pType padType, args ...sql.Expression) (sql.Expression, error) {
argLen := len(args)
if argLen != 3 {
Expand All @@ -35,34 +37,34 @@ func NewPad(pType padType, args ...sql.Expression) (sql.Expression, error) {
// Pad is a function that pads a string with another string.
type Pad struct {
str sql.Expression
len sql.Expression
length sql.Expression
padStr sql.Expression
padType padType
}

// Children implements the Expression interface.
func (p *Pad) Children() []sql.Expression {
return []sql.Expression{p.str, p.len, p.padStr}
return []sql.Expression{p.str, p.length, p.padStr}
}

// Resolved implements the Expression interface.
func (p *Pad) Resolved() bool {
return p.str.Resolved() && p.len.Resolved() && (p.padStr.Resolved())
return p.str.Resolved() && p.length.Resolved() && (p.padStr.Resolved())
}

// IsNullable implements the Expression interface.
func (p *Pad) IsNullable() bool {
return p.str.IsNullable() || p.len.IsNullable() || p.padStr.IsNullable()
return p.str.IsNullable() || p.length.IsNullable() || p.padStr.IsNullable()
}

// Type implements the Expression interface.
func (p *Pad) Type() sql.Type { return sql.Text }

func (p *Pad) String() string {
if p.padType == leftPadType {
return fmt.Sprintf("lpad(%s, %s, %s)", p.str, p.len, p.padStr)
if p.padType == lPadType {
return fmt.Sprintf("lpad(%s, %s, %s)", p.str, p.length, p.padStr)
}
return fmt.Sprintf("rpad(%s, %s, %s)", p.str, p.len, p.padStr)
return fmt.Sprintf("rpad(%s, %s, %s)", p.str, p.length, p.padStr)
}

// TransformUp implements the Expression interface.
Expand All @@ -72,7 +74,7 @@ func (p *Pad) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
return nil, err
}

len, err := p.len.TransformUp(f)
len, err := p.length.TransformUp(f)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -104,7 +106,7 @@ func (p *Pad) Eval(
return nil, sql.ErrInvalidType.New(reflect.TypeOf(str))
}

length, err := p.len.Eval(ctx, row)
length, err := p.length.Eval(ctx, row)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -147,18 +149,23 @@ func padString(str string, length int64, padStr string, padType padType) (string
}

padLen := int(length - int64(len(str)))
quo, rem := divmod(int64(padLen), int64(len(padStr)))
quo, rem, err := divmod(int64(padLen), int64(len(padStr)))
if err != nil {
return "", err
}

if padType == leftPadType {
if padType == lPadType {
result := strings.Repeat(padStr, int(quo)) + padStr[:rem] + str
return result[:length], nil
} else {
result := str + strings.Repeat(padStr, int(quo)) + padStr[:rem]
return result[(int64(len(result)) - length):], nil
}
result := str + strings.Repeat(padStr, int(quo)) + padStr[:rem]
return result[(int64(len(result)) - length):], nil
}

func divmod(a, b int64) (quotient, remainder int64) {
func divmod(a, b int64) (quotient, remainder int64, err error) {
if b == 0 {
return 0, 0, ErrDivisionByZero.New()
}
quotient = a / b
remainder = a % b
return
Expand Down
4 changes: 2 additions & 2 deletions sql/expression/function/rpad_lpad_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

func TestLPad(t *testing.T) {
f, err := NewPad(
leftPadType,
lPadType,
expression.NewGetField(0, sql.Text, "str", false),
expression.NewGetField(1, sql.Int64, "len", false),
expression.NewGetField(2, sql.Text, "padStr", false),
Expand Down Expand Up @@ -60,7 +60,7 @@ func TestLPad(t *testing.T) {

func TestRPad(t *testing.T) {
f, err := NewPad(
rightPadType,
rPadType,
expression.NewGetField(0, sql.Text, "str", false),
expression.NewGetField(1, sql.Int64, "len", false),
expression.NewGetField(2, sql.Text, "padStr", false),
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy