github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/or.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 HandleOrNullCol(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 vec.Col.([]bool)[0] = true 34 } else { 35 nulls.Add(vec.Nsp, 0) 36 } 37 return vec, nil 38 } else { 39 length := vector.Length(v2) 40 vec := allocateBoolVector(length, proc) 41 value := v2.Col.([]bool) 42 vcols := vec.Col.([]bool) 43 for i := 0; i < int(length); i++ { 44 if value[i] { 45 vcols[i] = true 46 } else { 47 nulls.Add(vec.Nsp, uint64(i)) 48 } 49 } 50 return vec, nil 51 } 52 } else { 53 if v1.IsScalar() { 54 vec := proc.AllocScalarVector(boolType) 55 vec.Col = make([]bool, 1) 56 value := v1.Col.([]bool)[0] 57 if value { 58 vec.Col.([]bool)[0] = true 59 } else { 60 nulls.Add(vec.Nsp, 0) 61 } 62 return vec, nil 63 } else { 64 length := vector.Length(v1) 65 vec := allocateBoolVector(length, proc) 66 value := v1.Col.([]bool) 67 vcols := vec.Col.([]bool) 68 for i := 0; i < int(length); i++ { 69 if value[i] { 70 vcols[i] = true 71 } else { 72 nulls.Add(vec.Nsp, uint64(i)) 73 } 74 } 75 return vec, nil 76 } 77 } 78 } 79 80 func ScalarOrNotScalar(_, nsv *vector.Vector, col1, col2 []bool, proc *process.Process) (*vector.Vector, error) { 81 length := vector.Length(nsv) 82 vec := allocateBoolVector(length, proc) 83 nulls.Or(nsv.Nsp, nil, vec.Nsp) 84 vcols := vec.Col.([]bool) 85 value := col1[0] 86 for i := range vcols { 87 vcols[i] = value || col2[i] 88 if nulls.Contains(nsv.Nsp, uint64(i)) && value { 89 vec.Nsp.Np.Remove(uint64(i)) 90 } 91 } 92 return vec, nil 93 } 94 95 func Or(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 96 v1, v2 := vs[0], vs[1] 97 col1, col2 := vector.MustTCols[bool](v1), vector.MustTCols[bool](v2) 98 if v1.IsScalarNull() || v2.IsScalarNull() { 99 return HandleOrNullCol(vs, proc) 100 } 101 102 c1, c2 := v1.IsScalar(), v2.IsScalar() 103 switch { 104 case c1 && c2: 105 vec := proc.AllocScalarVector(boolType) 106 vec.Col = make([]bool, 1) 107 vec.Col.([]bool)[0] = col1[0] || col2[0] 108 return vec, nil 109 case c1 && !c2: 110 return ScalarOrNotScalar(v1, v2, col1, col2, proc) 111 case !c1 && c2: 112 return ScalarOrNotScalar(v2, v1, col2, col1, proc) 113 } 114 // case !c1 && !c2 115 length := vector.Length(v1) 116 vec := allocateBoolVector(length, proc) 117 nulls.Or(v1.Nsp, v2.Nsp, vec.Nsp) 118 vcols := vec.Col.([]bool) 119 for i := range vcols { 120 vcols[i] = col1[i] || col2[i] 121 } 122 if nulls.Any(v1.Nsp) { 123 rows := v1.Nsp.Np.ToArray() 124 cols := v2.Col.([]bool) 125 for _, row := range rows { 126 if !nulls.Contains(v2.Nsp, row) && cols[row] { 127 vec.Nsp.Np.Remove(row) 128 } 129 } 130 } 131 if nulls.Any(v2.Nsp) { 132 rows := v2.Nsp.Np.ToArray() 133 cols := v1.Col.([]bool) 134 for _, row := range rows { 135 if !nulls.Contains(v1.Nsp, row) && cols[row] { 136 vec.Nsp.Np.Remove(row) 137 } 138 } 139 } 140 return vec, nil 141 }