/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.drill.exec.expr.fn.impl; import org.apache.drill.exec.expr.DrillSimpleFunc; import org.apache.drill.exec.expr.annotations.FunctionTemplate; import org.apache.drill.exec.expr.annotations.Output; import org.apache.drill.exec.expr.annotations.Param; import org.apache.drill.exec.expr.annotations.Workspace; import org.apache.drill.exec.expr.holders.BigIntHolder; import org.apache.drill.exec.expr.holders.BitHolder; import org.apache.drill.exec.expr.holders.Float4Holder; import org.apache.drill.exec.expr.holders.Float8Holder; import org.apache.drill.exec.expr.holders.IntHolder; import org.apache.drill.exec.expr.holders.RepeatedBigIntHolder; import org.apache.drill.exec.expr.holders.RepeatedBitHolder; import org.apache.drill.exec.expr.holders.RepeatedFloat4Holder; import org.apache.drill.exec.expr.holders.RepeatedFloat8Holder; import org.apache.drill.exec.expr.holders.RepeatedIntHolder; import org.apache.drill.exec.expr.holders.RepeatedTinyIntHolder; import org.apache.drill.exec.expr.holders.RepeatedVarCharHolder; import org.apache.drill.exec.expr.holders.TinyIntHolder; import org.apache.drill.exec.expr.holders.VarCharHolder; public class SimpleRepeatedFunctions { private SimpleRepeatedFunctions() { } // TODO - replace with a freemarker template and fill out the rest of the types // focused on getting functions defined for JSON types as this is the primary format // users are extracting repeated data out of currently @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthBigInt implements DrillSimpleFunc { @Param RepeatedBigIntHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthTinyInt implements DrillSimpleFunc { @Param RepeatedTinyIntHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } /* // TODO - need to confirm that these work SMP: They do not @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthMap implements DrillSimpleFunc { @Param RepeatedMapHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } // TODO - need to confirm that these work SMP: They do not @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthList implements DrillSimpleFunc { @Param RepeatedListHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } */ @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthBit implements DrillSimpleFunc { @Param RepeatedBitHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthFloat4 implements DrillSimpleFunc { @Param RepeatedFloat4Holder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthFloat8 implements DrillSimpleFunc { @Param RepeatedFloat8Holder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthInt implements DrillSimpleFunc { @Param RepeatedIntHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } @FunctionTemplate(name = "repeated_count", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class RepeatedLengthVarChar implements DrillSimpleFunc { @Param RepeatedVarCharHolder input; @Output IntHolder out; public void setup() { } public void eval() { out.value = input.end - input.start; } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsBigInt implements DrillSimpleFunc { @Param RepeatedBigIntHolder listToSearch; @Param BigIntHolder targetValue; @Output BitHolder out; public void setup() { } public void eval() { out.value = 0; for (int i = listToSearch.start; i < listToSearch.end; i++) { if (listToSearch.vector.getAccessor().get(i) == targetValue.value) { out.value = 1; break; } } } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsInt implements DrillSimpleFunc { @Param RepeatedIntHolder listToSearch; @Param IntHolder targetValue; @Output BitHolder out; public void setup() { } public void eval() { out.value = 0; for (int i = listToSearch.start; i < listToSearch.end; i++) { if (listToSearch.vector.getAccessor().get(i) == targetValue.value) { out.value = 1; break; } } } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsTinyInt implements DrillSimpleFunc { @Param RepeatedTinyIntHolder listToSearch; @Param TinyIntHolder targetValue; @Output BitHolder out; public void setup() { } public void eval() { for (int i = listToSearch.start; i < listToSearch.end; i++) { if (listToSearch.vector.getAccessor().get(i) == targetValue.value) { out.value = 1; break; } } } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsBit implements DrillSimpleFunc { @Param RepeatedBitHolder listToSearch; @Param BitHolder targetValue; @Output BitHolder out; public void setup() { } public void eval() { out.value = 0; for (int i = listToSearch.start; i < listToSearch.end; i++) { if (listToSearch.vector.getAccessor().get(i) == targetValue.value) { out.value = 1; break; } } } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsFloat4 implements DrillSimpleFunc { @Param RepeatedFloat4Holder listToSearch; @Param Float4Holder targetValue; @Output BitHolder out; public void setup() { } public void eval() { out.value = 0; for (int i = listToSearch.start; i < listToSearch.end; i++) { if (listToSearch.vector.getAccessor().get(i) == targetValue.value) { out.value = 1; break; } } } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsFloat8 implements DrillSimpleFunc { @Param RepeatedFloat8Holder listToSearch; @Param Float8Holder targetValue; @Output BitHolder out; public void setup() { } public void eval() { out.value = 0; for (int i = listToSearch.start; i < listToSearch.end; i++) { if (listToSearch.vector.getAccessor().get(i) == targetValue.value) { out.value = 1; break; } } } } @FunctionTemplate(name = "repeated_contains", scope = FunctionTemplate.FunctionScope.SIMPLE) public static class ContainsVarChar implements DrillSimpleFunc { @Param RepeatedVarCharHolder listToSearch; @Param VarCharHolder targetValue; @Workspace VarCharHolder currVal; @Workspace java.util.regex.Matcher matcher; @Workspace org.apache.drill.exec.expr.fn.impl.CharSequenceWrapper charSequenceWrapper; @Output BitHolder out; public void setup() { currVal = new VarCharHolder(); matcher = java.util.regex.Pattern.compile( org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(targetValue.start, targetValue.end, targetValue.buffer)).matcher(""); charSequenceWrapper = new org.apache.drill.exec.expr.fn.impl.CharSequenceWrapper(); matcher.reset(charSequenceWrapper); } public void eval() { for (int i = listToSearch.start; i < listToSearch.end; i++) { out.value = 0; listToSearch.vector.getAccessor().get(i, currVal); charSequenceWrapper.setBuffer(currVal.start, currVal.end, currVal.buffer); // Reusing same charSequenceWrapper, no need to pass it in. // This saves one method call since reset(CharSequence) calls reset() matcher.reset(); if(matcher.find()) { out.value = 1; break; } } } } }