github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/and.go (about) 1 // Copyright 2022 Matrix Origin 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 operator 16 17 import ( 18 "github.com/matrixorigin/matrixone/pkg/container/nulls" 19 "github.com/matrixorigin/matrixone/pkg/container/vector" 20 "github.com/matrixorigin/matrixone/pkg/vm/process" 21 ) 22 23 func HandleAndNullCol(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 24 v1, v2 := vs[0], vs[1] 25 if v1.IsScalarNull() { 26 if v2.IsScalarNull() { 27 return proc.AllocScalarNullVector(boolType), nil 28 } else if v2.IsScalar() { 29 vec := proc.AllocScalarVector(boolType) 30 vec.Col = make([]bool, 1) 31 value := v2.Col.([]bool)[0] 32 if value { 33 nulls.Add(vec.Nsp, 0) 34 } 35 return vec, nil 36 } else { 37 length := vector.Length(v2) 38 vec := allocateBoolVector(length, proc) 39 value := v2.Col.([]bool) 40 for i := 0; i < int(length); i++ { 41 if value[i] || nulls.Contains(v2.Nsp, uint64(i)) { 42 nulls.Add(vec.Nsp, uint64(i)) 43 } 44 } 45 return vec, nil 46 } 47 } else { 48 if v1.IsScalar() { 49 vec := proc.AllocScalarVector(boolType) 50 vec.Col = make([]bool, 1) 51 value := v1.Col.([]bool)[0] 52 if value { 53 nulls.Add(vec.Nsp, 0) 54 } 55 return vec, nil 56 } else { 57 length := vector.Length(v1) 58 vec := allocateBoolVector(length, proc) 59 value := v1.Col.([]bool) 60 for i := 0; i < int(length); i++ { 61 if value[i] || nulls.Contains(v1.Nsp, uint64(i)) { 62 nulls.Add(vec.Nsp, uint64(i)) 63 } 64 } 65 return vec, nil 66 } 67 } 68 } 69 70 func ScalarAndNotScalar(_, nsv *vector.Vector, col1, col2 []bool, proc *process.Process) (*vector.Vector, error) { 71 length := vector.Length(nsv) 72 vec := allocateBoolVector(length, proc) 73 vcols := vec.Col.([]bool) 74 value := col1[0] 75 for i := range vcols { 76 vcols[i] = value && col2[i] 77 } 78 if value { 79 nulls.Or(nsv.Nsp, nil, vec.Nsp) 80 } 81 return vec, nil 82 } 83 84 func And(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 85 v1, v2 := vs[0], vs[1] 86 col1, col2 := vector.MustTCols[bool](v1), vector.MustTCols[bool](v2) 87 if v1.IsScalarNull() || v2.IsScalarNull() { 88 return HandleAndNullCol(vs, proc) 89 } 90 91 c1, c2 := v1.IsScalar(), v2.IsScalar() 92 switch { 93 case c1 && c2: 94 vec := proc.AllocScalarVector(boolType) 95 vec.Col = make([]bool, 1) 96 vec.Col.([]bool)[0] = col1[0] && col2[0] 97 return vec, nil 98 case c1 && !c2: 99 return ScalarAndNotScalar(v1, v2, col1, col2, proc) 100 case !c1 && c2: 101 return ScalarAndNotScalar(v2, v1, col2, col1, proc) 102 } 103 // case !c1 && !c2 104 length := vector.Length(v1) 105 vec := allocateBoolVector(length, proc) 106 nulls.Or(v1.Nsp, v2.Nsp, vec.Nsp) 107 vcols := vec.Col.([]bool) 108 for i := range vcols { 109 vcols[i] = col1[i] && col2[i] 110 } 111 if nulls.Any(v1.Nsp) { 112 rows := v1.Nsp.Np.ToArray() 113 cols := v2.Col.([]bool) 114 for _, row := range rows { 115 if !nulls.Contains(v2.Nsp, row) && !cols[row] { 116 vec.Nsp.Np.Remove(row) 117 } 118 } 119 } 120 if nulls.Any(v2.Nsp) { 121 rows := v2.Nsp.Np.ToArray() 122 cols := v1.Col.([]bool) 123 for _, row := range rows { 124 if !nulls.Contains(v1.Nsp, row) && !cols[row] { 125 vec.Nsp.Np.Remove(row) 126 } 127 } 128 } 129 return vec, nil 130 }