github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/datediff/datediff.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 package datediff 15 16 import ( 17 "github.com/matrixorigin/matrixone/pkg/container/nulls" 18 "github.com/matrixorigin/matrixone/pkg/container/types" 19 ) 20 21 func DateDiff(lv, rv []types.Date, rs []int64) []int64 { 22 for i := range lv { 23 rs[i] = int64(lv[i] - rv[i]) 24 } 25 return rs 26 } 27 28 func DateDiffRightConst(lv []types.Date, rv types.Date, rs []int64) []int64 { 29 for i := range lv { 30 rs[i] = int64(lv[i] - rv) 31 } 32 return rs 33 } 34 35 func DateDiffLeftConst(lv types.Date, rv []types.Date, rs []int64) []int64 { 36 for i := range rv { 37 rs[i] = int64(lv - rv[i]) 38 } 39 return rs 40 } 41 42 func DateDiffAllConst(lv, rv types.Date, rs []int64) []int64 { 43 rs[0] = int64(lv - rv) 44 return rs 45 } 46 47 func TimeStampDiff(unit string, expr1, expr2 types.Datetime) (int64, error) { 48 return expr2.DateTimeDiffWithUnit(unit, expr1) 49 } 50 51 func TimeStampDiffWithCols(units []string, expr1, expr2 []types.Datetime, unitNs, firstNs, secondNs, rsNs *nulls.Nulls, rs []int64, maxLen int) error { 52 var unit string 53 if len(expr1) == 1 && len(expr2) == 1 { 54 unitsLen := len(units) 55 for i := 0; i < maxLen; i++ { 56 if determineNulls(unitsLen, 1, 1, unitNs, firstNs, secondNs, i) { 57 nulls.Add(rsNs, uint64(i)) 58 continue 59 } 60 if unitsLen == 1 { 61 unit = units[0] 62 } else { 63 unit = units[i] 64 } 65 66 res, err := TimeStampDiff(unit, expr1[0], expr2[0]) 67 if err != nil { 68 return err 69 } 70 rs[i] = res 71 } 72 } else if len(expr1) == 1 { 73 unitsLen := len(units) 74 for i := 0; i < maxLen; i++ { 75 if determineNulls(unitsLen, 1, maxLen, unitNs, firstNs, secondNs, i) { 76 nulls.Add(rsNs, uint64(i)) 77 continue 78 } 79 if unitsLen == 1 { 80 unit = units[0] 81 } else { 82 unit = units[i] 83 } 84 85 res, err := TimeStampDiff(unit, expr1[0], expr2[i]) 86 if err != nil { 87 return err 88 } 89 rs[i] = res 90 } 91 } else if len(expr2) == 1 { 92 unitsLen := len(units) 93 for i := 0; i < maxLen; i++ { 94 if determineNulls(unitsLen, maxLen, 1, unitNs, firstNs, secondNs, i) { 95 nulls.Add(rsNs, uint64(i)) 96 continue 97 } 98 if unitsLen == 1 { 99 unit = units[0] 100 } else { 101 unit = units[i] 102 } 103 104 res, err := TimeStampDiff(unit, expr1[i], expr2[0]) 105 if err != nil { 106 return err 107 } 108 rs[i] = res 109 } 110 } else { 111 unitsLen := len(units) 112 for i := 0; i < maxLen; i++ { 113 if determineNulls(unitsLen, maxLen, maxLen, unitNs, firstNs, secondNs, i) { 114 nulls.Add(rsNs, uint64(i)) 115 continue 116 } 117 if unitsLen == 1 { 118 unit = units[0] 119 } else { 120 unit = units[i] 121 } 122 123 res, err := TimeStampDiff(unit, expr1[i], expr2[i]) 124 if err != nil { 125 return err 126 } 127 rs[i] = res 128 } 129 } 130 return nil 131 } 132 133 func determineNulls(unitL, firstL, secondL int, unitNs, firstNs, secondNs *nulls.Nulls, i int) bool { 134 var uintIndex int 135 var firstIndex int 136 var secondIndex int 137 138 if unitL == 1 { 139 uintIndex = 0 140 } else { 141 uintIndex = i 142 } 143 144 if firstL == 1 { 145 firstIndex = 0 146 } else { 147 firstIndex = i 148 } 149 150 if secondL == 1 { 151 secondIndex = 0 152 } else { 153 secondIndex = 1 154 } 155 return nulls.Contains(unitNs, uint64(uintIndex)) || nulls.Contains(firstNs, uint64(firstIndex)) || nulls.Contains(secondNs, uint64(secondIndex)) 156 }