Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evalEngine: Implement ELT and FIELD #15249

Merged
merged 9 commits into from
Apr 1, 2024
Merged
114 changes: 71 additions & 43 deletions go/vt/vtgate/evalengine/compiler_asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2345,7 +2345,7 @@ func (asm *assembler) Fn_BIT_LENGTH() {
}, "FN BIT_LENGTH VARCHAR(SP-1)")
}

func (asm *assembler) Fn_FIELD(args int, containsOnlyString, containsOnlyInt64 bool) {
func (asm *assembler) Fn_FIELD_i(args int) {
asm.adjustStack(-args + 1)
asm.emit(func(env *ExpressionEnv) int {
if env.vm.stack[env.vm.sp-args] == nil {
Expand All @@ -2354,60 +2354,57 @@ func (asm *assembler) Fn_FIELD(args int, containsOnlyString, containsOnlyInt64 b
return 1
}

if containsOnlyInt64 {
tar := env.vm.stack[env.vm.sp-args].(*evalInt64)
tar := env.vm.stack[env.vm.sp-args].(*evalInt64)

for i := range args - 1 {
if env.vm.stack[env.vm.sp-args+i+1] == nil {
continue
}
for i := range args - 1 {
if env.vm.stack[env.vm.sp-args+i+1] == nil {
continue
}

arg := env.vm.stack[env.vm.sp-args+i+1].(*evalInt64)
arg := env.vm.stack[env.vm.sp-args+i+1].(*evalInt64)

if tar.i == arg.i {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(int64(i + 1))
env.vm.sp -= args - 1
return 1
}
if tar.i == arg.i {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(int64(i + 1))
env.vm.sp -= args - 1
return 1
}
} else if containsOnlyString {
tar := env.vm.stack[env.vm.sp-args].(*evalBytes)
}

for i := range args - 1 {
if env.vm.stack[env.vm.sp-args+i+1] == nil {
continue
}
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(0)
env.vm.sp -= args - 1
return 1
}, "FN FIELD INT64(SP-%d)...INT64(SP-1)", args)
}

str := env.vm.stack[env.vm.sp-args+i+1].(*evalBytes)
func (asm *assembler) Fn_FIELD_b(args int) {
asm.adjustStack(-args + 1)
asm.emit(func(env *ExpressionEnv) int {
if env.vm.stack[env.vm.sp-args] == nil {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(0)
env.vm.sp -= args - 1
return 1
}

// Compare target and current string
if len(tar.bytes) == len(str.bytes) {
eq := true
for i, b := range tar.bytes {
if str.bytes[i] != b {
eq = false
break
}
}
tar := env.vm.stack[env.vm.sp-args].(*evalBytes)

if eq {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(int64(i + 1))
env.vm.sp -= args - 1
return 1
}
}
for i := range args - 1 {
if env.vm.stack[env.vm.sp-args+i+1] == nil {
continue
}
} else {
tar := env.vm.stack[env.vm.sp-args].(*evalFloat)

for i := range args - 1 {
if env.vm.stack[env.vm.sp-args+i+1] == nil {
continue
}
str := env.vm.stack[env.vm.sp-args+i+1].(*evalBytes)

arg := env.vm.stack[env.vm.sp-args+i+1].(*evalFloat)
// Compare target and current string
if len(tar.bytes) == len(str.bytes) {
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
eq := true
for i, b := range tar.bytes {
if str.bytes[i] != b {
eq = false
break
}
}

if tar.f == arg.f {
if eq {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(int64(i + 1))
env.vm.sp -= args - 1
return 1
Expand All @@ -2421,6 +2418,37 @@ func (asm *assembler) Fn_FIELD(args int, containsOnlyString, containsOnlyInt64 b
}, "FN FIELD VARCHAR(SP-%d)...VARCHAR(SP-1)", args)
dbussink marked this conversation as resolved.
Show resolved Hide resolved
}

func (asm *assembler) Fn_FIELD_f(args int) {
asm.adjustStack(-args + 1)
asm.emit(func(env *ExpressionEnv) int {
if env.vm.stack[env.vm.sp-args] == nil {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(0)
env.vm.sp -= args - 1
return 1
}

tar := env.vm.stack[env.vm.sp-args].(*evalFloat)

for i := range args - 1 {
if env.vm.stack[env.vm.sp-args+i+1] == nil {
continue
}

arg := env.vm.stack[env.vm.sp-args+i+1].(*evalFloat)

if tar.f == arg.f {
env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(int64(i + 1))
env.vm.sp -= args - 1
return 1
}
}

env.vm.stack[env.vm.sp-args] = env.vm.arena.newEvalInt64(0)
env.vm.sp -= args - 1
return 1
}, "FN FIELD VARCHAR(SP-%d)...VARCHAR(SP-1)", args)
}

func (asm *assembler) Fn_ELT(args int, tt sqltypes.Type, tc collations.TypedCollation) {
asm.adjustStack(-args + 1)
asm.emit(func(env *ExpressionEnv) int {
Expand Down
8 changes: 6 additions & 2 deletions go/vt/vtgate/evalengine/fn_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
tar, err = evalToVarchar(args[0], call.collate, true)
if err != nil {
return nil, err
}

Check warning on line 182 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L182

Added line #L182 was not covered by tests
}

for i, arg := range args[1:] {
Expand Down Expand Up @@ -213,9 +213,9 @@
}
} else {
tar, _ := evalToFloat(args[0])

for i, arg := range args[1:] {
if arg == nil {

Check warning on line 218 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L216-L218

Added lines #L216 - L218 were not covered by tests
continue
}

Expand All @@ -227,9 +227,9 @@
}

return newEvalInt64(0), nil
}

func (call *builtinField) compile(c *compiler) (ctype, error) {

Check warning on line 232 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L230-L232

Added lines #L230 - L232 were not covered by tests
strs := make([]ctype, len(call.Arguments))

for i, arg := range call.Arguments {
Expand Down Expand Up @@ -260,6 +260,8 @@
_ = c.compileToInt64(str, offset)
c.asm.jumpDestination(skip)
}

c.asm.Fn_FIELD_i(len(call.Arguments))
} else if containsOnlyString {
for i, str := range strs {
offset := len(strs) - i
Expand All @@ -271,7 +273,9 @@
c.asm.Convert_xce(offset, sqltypes.VarChar, call.collate)
}
c.asm.jumpDestination(skip)
}

Check warning on line 276 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L276

Added line #L276 was not covered by tests

c.asm.Fn_FIELD_b(len(call.Arguments))
} else {
for i, str := range strs {
offset := len(strs) - i
Expand All @@ -280,9 +284,9 @@
c.asm.Convert_xf(offset)
beingnoble03 marked this conversation as resolved.
Show resolved Hide resolved
c.asm.jumpDestination(skip)
}
}

c.asm.Fn_FIELD(len(call.Arguments), containsOnlyString, containsOnlyInt64)
c.asm.Fn_FIELD_f(len(call.Arguments))
}

return ctype{Type: sqltypes.Int64, Col: collationNumeric}, nil
}
Expand Down Expand Up @@ -330,7 +334,7 @@
}

return newEvalRaw(tt, b.bytes, b.col), nil
}

Check warning on line 337 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L337

Added line #L337 was not covered by tests

func (call *builtinElt) compile(c *compiler) (ctype, error) {
args := make([]ctype, len(call.Arguments))
Expand All @@ -350,7 +354,7 @@
skip = c.compileNullCheck1(args[i])
continue
}

Check warning on line 357 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L357

Added line #L357 was not covered by tests
tt = concatSQLType(args[i].Type, tt)
err = ca.add(args[i].Col, c.env.CollationEnv())
if err != nil {
Expand All @@ -363,7 +367,7 @@
// collation instead of using the numeric collation.
if tc.Coercibility == collations.CoerceNumeric {
tc = typedCoercionCollation(tt, call.collate)
}

Check warning on line 370 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L370

Added line #L370 was not covered by tests

_ = c.compileToInt64(args[0], len(args))

Expand All @@ -380,7 +384,7 @@
fromCharset := colldata.Lookup(arg.Col.Collation).Charset()
toCharset := colldata.Lookup(tc.Collation).Charset()
if fromCharset != toCharset && !toCharset.IsSuperset(fromCharset) {
c.asm.Convert_xce(offset, arg.Type, tc.Collation)

Check warning on line 387 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L387

Added line #L387 was not covered by tests
}
default:
c.asm.Convert_xce(offset, arg.Type, tc.Collation)
Expand All @@ -391,7 +395,7 @@

c.asm.Fn_ELT(len(args), tt, tc)
c.asm.jumpDestination(skip)

Check warning on line 398 in go/vt/vtgate/evalengine/fn_string.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/evalengine/fn_string.go#L398

Added line #L398 was not covered by tests
return ctype{Type: tt, Col: tc, Flag: flagNullable}, nil
}

Expand Down
Loading