blob: 58b8d0d5a186018da61c15fd388e533c27810c0e [file] [log] [blame]
/*
* 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.udfs;
import io.netty.buffer.DrillBuf;
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.holders.VarCharHolder;
import javax.inject.Inject;
public class PhoneticFunctions {
/**
* The Caverphone function is a phonetic matching function. This is an algorithm created by the Caversham Project at the University of Otago. It implements the Caverphone 1.0 algorithm.
* <p>
* <p>
* Usage: SELECT caverphone1( string ) FROM...
*/
@FunctionTemplate(name = "caverphone1", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class Caverphone1Function implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.Caverphone1().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* The Caverphone function is a phonetic matching function. This is an algorithm created by the Caversham Project at the University of Otago. It implements the Caverphone 2.0 algorithm.
* <p>
* Usage: SELECT caverphone2( string ) FROM...
*/
@FunctionTemplate(name = "caverphone2", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class Caverphone2Function implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.Caverphone2().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Encodes a string into a Cologne Phonetic value.
* Implements the Kölner Phonetik (Cologne Phonetic) algorithm issued by Hans Joachim Postel in 1969.
* <p>
* The Kölner Phonetik is a phonetic algorithm which is optimized for the German language.
* It is related to the well-known soundex algorithm.
* <p>
* Usage: SELECT cologne_phonetic( string ) FROM...
*/
@FunctionTemplate(name = "cologne_phonetic", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class ColognePhoneticFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.ColognePhonetic().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Encodes a string into a Daitch-Mokotoff Soundex value.
* The Daitch-Mokotoff Soundex algorithm is a refinement of the Russel and American Soundex algorithms,
* yielding greater accuracy in matching especially Slavish and Yiddish surnames with similar pronunciation
* but differences in spelling.
* <p>
* The main differences compared to the other soundex variants are:
* coded names are 6 digits long
* the initial character of the name is coded
* rules to encoded multi-character n-grams
* multiple possible encodings for the same name (branching)
* <p>
* Usage: SELECT dm_soundex( string ) FROM...
*/
@FunctionTemplate(name = "dm_soundex", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class DaitchMokotoffFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.DaitchMokotoffSoundex().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Match Rating Approach Phonetic Algorithm Developed by Western Airlines in 1977.
* Usage: SELECT match_rating_encoder( string ) FROM...
*/
@FunctionTemplate(name = "match_rating_encoder", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class MatchRatingFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.MatchRatingApproachEncoder().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* The New York State Identification and Intelligence System Phonetic Code, commonly known as NYSIIS, is a phonetic algorithm devised in 1970 as part of the New York State Identification and Intelligence System (now a part of the New York State Division of Criminal Justice Services). It features an accuracy increase of 2.7% over the traditional Soundex algorithm.
* Encodes a string into a NYSIIS value. NYSIIS is an encoding used to relate similar names, but can also be used as a general purpose scheme to find word with similar phonemes.
* <p>
* Usage: SELECT nysiis(string) FROM...
*/
@FunctionTemplate(name = "nysiis", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class NYSIISFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.Nysiis().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Encodes a string into a Refined Soundex value. Soundex is an encoding used to relate similar names, but can also be used as a general purpose scheme to find word with similar phonemes.
* <p>
* Usage: SELECT refined_soundex( string ) FROM...
*/
@FunctionTemplate(name = "refined_soundex", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class RefinedSoundexFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.RefinedSoundex().encode(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Encodes a string into a Soundex value. Soundex is an encoding used to relate similar names, but can also be used as a general purpose scheme to find word with similar phonemes.
* <p>
* Usage: SELECT soundex( string ) FROM...
*/
@FunctionTemplate(name = "soundex", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class SoundexFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.Soundex().soundex(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Implements the Metaphone phonetic algorithm (https://en.wikipedia.org/wiki/Metaphone),
* and calculates a given string's Metaphone value.
* <p>
* Usage: SELECT metaphone( string ) FROM...
*/
@FunctionTemplate(name = "metaphone", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class MetaphoneFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.Metaphone().metaphone(input);
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
/**
* Implements the Double Metaphone phonetic algorithm (https://en.wikipedia.org/wiki/Metaphone),
* and calculates a given string's Double Metaphone value.
* <p>
* Usage: SELECT double_metaphone( string ) FROM...
*/
@FunctionTemplate(name = "double_metaphone", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
public static class DoubleMetaphoneFunction implements DrillSimpleFunc {
@Param
VarCharHolder rawInput;
@Output
VarCharHolder out;
@Inject
DrillBuf buffer;
@Override
public void setup() {
}
@Override
public void eval() {
String input = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(rawInput.start, rawInput.end, rawInput.buffer);
String outputString = new org.apache.commons.codec.language.DoubleMetaphone().doubleMetaphone(input);
outputString = outputString == null ? "" : outputString;
byte[] output = outputString.getBytes(java.nio.charset.StandardCharsets.UTF_8);
out.buffer = buffer;
out.start = 0;
out.end = output.length;
buffer.setBytes(0, output);
}
}
}