// Copyright 2019 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. //go:build ignore // +build ignore package main import ( "bytes" "go/format" "io/ioutil" "log" "path/filepath" "text/template" . "github.com/pingcap/tidb/expression/generator/helper" ) var addOrSubTime = template.Must(template.New("").Parse(` {{ if eq $.FuncName "AddTime" }} // Copyright 2019 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. // Code generated by go generate in expression/generator; DO NOT EDIT. package expression import ( "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" ) {{ end }} {{ define "SetNull" }}{{if .Output.Fixed}}result.SetNull(i, true){{else}}result.AppendNull(){{end}} // fixed: {{.Output.Fixed }}{{ end }} {{ define "ConvertStringToDuration" }} {{ if and (ne .SigName "builtinAddStringAndStringSig") (ne .SigName "builtinSubStringAndStringSig") }} if !isDuration(arg1) { {{ template "SetNull" . }} continue }{{ end }} sc := b.ctx.GetSessionVars().StmtCtx arg1Duration, err := types.ParseDuration(sc, arg1, {{if eq .Output.TypeName "String"}}getFsp4TimeAddSub{{else}}types.GetFsp{{end}}(arg1)) if err != nil { if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) { sc.AppendWarning(err) {{ template "SetNull" . }} continue } return err } {{ end }} {{ range .Sigs }} {{ if .AllNull}} func (b *{{.SigName}}) vecEval{{ .Output.TypeName }}(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() {{ if .Output.Fixed }} result.Resize{{ .Output.TypeNameInColumn }}(n, true) {{ else }} result.Reserve{{ .Output.TypeNameInColumn }}(n) for i := 0; i < n; i++ { result.AppendNull() } {{ end }} return nil } {{ else }} func (b *{{.SigName}}) vecEval{{ .Output.TypeName }}(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() {{ $reuse := (and (eq .TypeA.TypeName .Output.TypeName) .TypeA.Fixed) }} {{ if $reuse }} if err := b.args[0].VecEval{{ .TypeA.TypeName }}(b.ctx, input, result); err != nil { return err } buf0 := result {{ else }} buf0, err := b.bufAllocator.get(types.ET{{.TypeA.ETName}}, n) if err != nil { return err } defer b.bufAllocator.put(buf0) if err := b.args[0].VecEval{{ .TypeA.TypeName }}(b.ctx, input, buf0); err != nil { return err } {{ end }} {{ if or (eq .SigName "builtinAddStringAndStringSig") (eq .SigName "builtinSubStringAndStringSig") }} arg1Type := b.args[1].GetType() if mysql.HasBinaryFlag(arg1Type.Flag) { result.Reserve{{ .Output.TypeNameInColumn }}(n) for i := 0; i < n; i++ { result.AppendNull() } return nil } {{ end }} buf1, err := b.bufAllocator.get(types.ET{{.TypeB.ETName}}, n) if err != nil { return err } defer b.bufAllocator.put(buf1) if err := b.args[1].VecEval{{ .TypeB.TypeName }}(b.ctx, input, buf1); err != nil { return err } {{ if $reuse }} result.MergeNulls(buf1) {{ else if .Output.Fixed}} result.Resize{{ .Output.TypeNameInColumn }}(n, false) result.MergeNulls(buf0, buf1) {{ else }} result.Reserve{{ .Output.TypeNameInColumn}}(n) {{ end }} {{ if .TypeA.Fixed }} arg0s := buf0.{{.TypeA.TypeNameInColumn}}s() {{ end }} {{ if .TypeB.Fixed }} arg1s := buf1.{{.TypeB.TypeNameInColumn}}s() {{ end }} {{ if .Output.Fixed }} resultSlice := result.{{.Output.TypeNameInColumn}}s() {{ end }} for i := 0; i < n; i++ { {{ if .Output.Fixed }} if result.IsNull(i) { continue } {{ else }} if buf0.IsNull(i) || buf1.IsNull(i) { result.AppendNull() continue } {{ end }} // get arg0 & arg1 {{ if .TypeA.Fixed }} arg0 := arg0s[i] {{ else }} arg0 := buf0.Get{{ .TypeA.TypeNameInColumn }}(i) {{ end }} {{ if .TypeB.Fixed }} arg1 := arg1s[i] {{ else }} arg1 := buf1.Get{{ .TypeB.TypeNameInColumn }}(i) {{ end }} // calculate {{ if or (eq .SigName "builtinAddDatetimeAndDurationSig") (eq .SigName "builtinSubDatetimeAndDurationSig") }} {{ if eq $.FuncName "AddTime" }} output, err := arg0.Add(b.ctx.GetSessionVars().StmtCtx, types.Duration{Duration: arg1, Fsp: -1}) {{ else }} sc := b.ctx.GetSessionVars().StmtCtx arg1Duration := types.Duration{Duration: arg1, Fsp: -1} arg1time, err := arg1Duration.ConvertToTime(sc, mysql.TypeDatetime) if err != nil { return err } tmpDuration := arg0.Sub(sc, &arg1time) output, err := tmpDuration.ConvertToTime(sc, arg0.Type()) {{ end }} if err != nil { return err } {{ else if or (eq .SigName "builtinAddDatetimeAndStringSig") (eq .SigName "builtinSubDatetimeAndStringSig") }} {{ if eq $.FuncName "AddTime" }} {{ template "ConvertStringToDuration" . }} output, err := arg0.Add(sc, arg1Duration) {{ else }} if !isDuration(arg1) { result.SetNull(i, true) // fixed: true continue } sc := b.ctx.GetSessionVars().StmtCtx arg1Duration, err := types.ParseDuration(sc, arg1, types.GetFsp(arg1)) if err != nil { if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) { sc.AppendWarning(err) result.SetNull(i, true) // fixed: true continue } return err } arg1time, err := arg1Duration.ConvertToTime(sc, mysql.TypeDatetime) if err != nil { return err } tmpDuration := arg0.Sub(sc, &arg1time) output, err := tmpDuration.ConvertToTime(sc, mysql.TypeDatetime) {{ end }} if err != nil { return err } {{ else if or (eq .SigName "builtinAddDurationAndDurationSig") (eq .SigName "builtinSubDurationAndDurationSig") }} {{ if eq $.FuncName "AddTime" }} output, err := types.AddDuration(arg0, arg1) if err != nil { return err } {{ else }} output, err := types.SubDuration(arg0, arg1) if err != nil { return err } {{ end }} {{ else if or (eq .SigName "builtinAddDurationAndStringSig") (eq .SigName "builtinSubDurationAndStringSig") }} {{ template "ConvertStringToDuration" . }} {{ if eq $.FuncName "AddTime" }} output, err := types.AddDuration(arg0, arg1Duration.Duration) if err != nil { return err } {{ else }} output, err := types.SubDuration(arg0, arg1Duration.Duration) if err != nil { return err } {{ end }} {{ else if or (eq .SigName "builtinAddStringAndDurationSig") (eq .SigName "builtinSubStringAndDurationSig") }} sc := b.ctx.GetSessionVars().StmtCtx fsp1 := int8(b.args[1].GetType().Decimal) arg1Duration := types.Duration{Duration: arg1, Fsp: fsp1} var output string if isDuration(arg0) { {{ if eq $.FuncName "AddTime" }} output, err = strDurationAddDuration(sc, arg0, arg1Duration) {{ else }} output, err = strDurationSubDuration(sc, arg0, arg1Duration) {{ end }} if err != nil { if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) { sc.AppendWarning(err) {{ template "SetNull" . }} continue } return err } } else { {{ if eq $.FuncName "AddTime" }} output, err = strDatetimeAddDuration(sc, arg0, arg1Duration) {{ else }} output, err = strDatetimeSubDuration(sc, arg0, arg1Duration) {{ end }} if err != nil { return err } } {{ else if or (eq .SigName "builtinAddStringAndStringSig") (eq .SigName "builtinSubStringAndStringSig") }} {{ template "ConvertStringToDuration" . }} var output string if isDuration(arg0) { {{ if eq $.FuncName "AddTime" }} output, err = strDurationAddDuration(sc, arg0, arg1Duration) {{ else }} output, err = strDurationSubDuration(sc, arg0, arg1Duration) {{ end }} if err != nil { if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) { sc.AppendWarning(err) {{ template "SetNull" . }} continue } return err } } else { {{ if eq $.FuncName "AddTime" }} output, err = strDatetimeAddDuration(sc, arg0, arg1Duration) {{ else }} output, err = strDatetimeSubDuration(sc, arg0, arg1Duration) {{ end }} if err != nil { return err } } {{ else if or (eq .SigName "builtinAddDateAndDurationSig") (eq .SigName "builtinSubDateAndDurationSig") }} fsp0 := int8(b.args[0].GetType().Decimal) fsp1 := int8(b.args[1].GetType().Decimal) arg1Duration := types.Duration{Duration: arg1, Fsp: fsp1} {{ if eq $.FuncName "AddTime" }} sum, err := types.Duration{Duration: arg0, Fsp: fsp0}.Add(arg1Duration) {{ else }} sum, err := types.Duration{Duration: arg0, Fsp: fsp0}.Sub(arg1Duration) {{ end }} if err != nil { return err } output := sum.String() {{ else if or (eq .SigName "builtinAddDateAndStringSig") (eq .SigName "builtinSubDateAndStringSig") }} {{ template "ConvertStringToDuration" . }} fsp0 := int8(b.args[0].GetType().Decimal) {{ if eq $.FuncName "AddTime" }} sum, err := types.Duration{Duration: arg0, Fsp: fsp0}.Add(arg1Duration) {{ else }} sum, err := types.Duration{Duration: arg0, Fsp: fsp0}.Sub(arg1Duration) {{ end }} if err != nil { return err } output := sum.String() {{ end }} // commit result {{ if .Output.Fixed }} resultSlice[i] = output {{ else }} result.Append{{ .Output.TypeNameInColumn }}(output) {{ end }} } return nil } {{ end }}{{/* if .AllNull */}} func (b *{{.SigName}}) vectorized() bool { return true } {{ end }}{{/* range */}} `)) var timeDiff = template.Must(template.New("").Parse(` {{ define "BufAllocator0" }} buf0, err := b.bufAllocator.get(types.ET{{.TypeA.ETName}}, n) if err != nil { return err } defer b.bufAllocator.put(buf0) {{ end }} {{ define "BufAllocator1" }} buf1, err := b.bufAllocator.get(types.ET{{.TypeB.ETName}}, n) if err != nil { return err } defer b.bufAllocator.put(buf1) {{ end }} {{ define "ArgsVecEval" }} if err := b.args[0].VecEval{{ .TypeA.TypeName }}(b.ctx, input, buf0); err != nil { return err } if err := b.args[1].VecEval{{ .TypeB.TypeName }}(b.ctx, input, buf1); err != nil { return err } {{ end }} {{ range . }} {{ $AIsString := (eq .TypeA.TypeName "String") }} {{ $BIsString := (eq .TypeB.TypeName "String") }} {{ $AIsTime := (eq .TypeA.TypeName "Time") }} {{ $BIsTime := (eq .TypeB.TypeName "Time") }} {{ $AIsDuration := (eq .TypeA.TypeName "Duration") }} {{ $BIsDuration := (eq .TypeB.TypeName "Duration") }} {{ $MaybeDuration := (or (or $AIsDuration $BIsDuration) (and $AIsString $AIsString)) }} {{ $reuseA := (eq .TypeA.TypeName "Duration") }} {{ $reuseB := (eq .TypeB.TypeName "Duration") }} {{ $reuse := (or $reuseA $reuseB ) }} {{ $noNull := (ne .SigName "builtinNullTimeDiffSig") }} func (b *{{.SigName}}) vecEvalDuration(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() {{- if not $noNull }} result.ResizeGoDuration(n, true) {{- else }} result.ResizeGoDuration(n, false) r64s := result.GoDurations() {{- if $reuseA }} buf0 := result {{- template "BufAllocator1" . }} {{- template "ArgsVecEval" . }} result.MergeNulls(buf1) {{- else if $reuseB }} buf1 := result {{- template "BufAllocator0" . }} {{- template "ArgsVecEval" . }} result.MergeNulls(buf0) {{- else }} {{- template "BufAllocator0" . }} {{- template "BufAllocator1" . }} {{- template "ArgsVecEval" . }} result.MergeNulls(buf0, buf1) {{- end }} {{- if .TypeA.Fixed }} arg0 := buf0.{{.TypeA.TypeNameInColumn}}s() {{- end }} {{- if .TypeB.Fixed }} arg1 := buf1.{{.TypeB.TypeNameInColumn}}s() {{- end }} {{- if (or $AIsDuration $BIsDuration) }} var ( lhs types.Duration rhs types.Duration ) {{- end }} {{- if or (or $AIsString $BIsString) (and $AIsTime $BIsTime) }} stmtCtx := b.ctx.GetSessionVars().StmtCtx {{- end }} for i:=0; i