Skip to content

Commit

Permalink
SQL: Add support for single parameter text manipulating functions (#3…
Browse files Browse the repository at this point in the history
…1874)

Added support for ASCII, BIT_LENGTH, CHAR, CHAR_LENGTH, LCASE, LENGTH, LTRIM, RTRIM, SPACE, UCASE functions.
Wherever Painless scripting is necessary (WHERE conditions, ORDER BY etc), those scripts are being used.
  • Loading branch information
astefan authored Jul 12, 2018
1 parent 2cfe703 commit edf83c1
Show file tree
Hide file tree
Showing 31 changed files with 1,227 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@
import org.elasticsearch.xpack.sql.expression.function.scalar.math.Sinh;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.Sqrt;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.Tan;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.Ascii;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.BitLength;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.Char;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.CharLength;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.LCase;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.LTrim;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.Length;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.RTrim;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.Space;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.UCase;
import org.elasticsearch.xpack.sql.parser.ParsingException;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.util.StringUtils;
Expand Down Expand Up @@ -134,6 +144,17 @@ public class FunctionRegistry {
def(Sinh.class, Sinh::new),
def(Sqrt.class, Sqrt::new),
def(Tan.class, Tan::new),
// String
def(Ascii.class, Ascii::new),
def(Char.class, Char::new),
def(BitLength.class, BitLength::new),
def(CharLength.class, CharLength::new),
def(LCase.class, LCase::new),
def(Length.class, Length::new),
def(LTrim.class, LTrim::new),
def(RTrim.class, RTrim::new),
def(Space.class, Space::new),
def(UCase.class, UCase::new),
// Special
def(Score.class, Score::new)));

Expand Down Expand Up @@ -299,6 +320,7 @@ interface BinaryFunctionBuilder<T> {
T build(Location location, Expression lhs, Expression rhs);
}

@SuppressWarnings("overloads")
private static FunctionDefinition def(Class<? extends Function> function, FunctionBuilder builder,
boolean datetime, String... aliases) {
String primaryName = normalize(function.getSimpleName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.elasticsearch.xpack.sql.expression.function.scalar.processor.runtime.ConstantProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.processor.runtime.HitExtractorProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.processor.runtime.Processor;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -46,6 +47,8 @@ public static List<NamedWriteableRegistry.Entry> getNamedWriteables() {
entries.add(new Entry(Processor.class, DateTimeProcessor.NAME, DateTimeProcessor::new));
// math
entries.add(new Entry(Processor.class, MathProcessor.NAME, MathProcessor::new));
// string
entries.add(new Entry(Processor.class, StringProcessor.NAME, StringProcessor::new));
return entries;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected BiFunction<Number, Number, Number> operation() {
}

@Override
protected NodeInfo<? extends Expression> info() {
protected NodeInfo<ATan2> info() {
return NodeInfo.create(this, ATan2::new, left(), right());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected BiFunction<Number, Number, Number> operation() {
}

@Override
protected NodeInfo<? extends Expression> info() {
protected NodeInfo<Power> info() {
return NodeInfo.create(this, Power::new, left(), right());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Returns the ASCII code of the leftmost character of the given (char) expression.
*/
public class Ascii extends UnaryStringFunction {

public Ascii(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<Ascii> info() {
return NodeInfo.create(this, Ascii::new, field());
}

@Override
protected Ascii replaceChild(Expression newChild) {
return new Ascii(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.ASCII;
}

@Override
public DataType dataType() {
return DataType.INTEGER;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Returns returns the number of bits contained within the value expression.
*/
public class BitLength extends UnaryStringFunction {

public BitLength(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<BitLength> info() {
return NodeInfo.create(this, BitLength::new, field());
}

@Override
protected BitLength replaceChild(Expression newChild) {
return new BitLength(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.BIT_LENGTH;
}

@Override
public DataType dataType() {
//TODO investigate if a data type Long (BIGINT) wouldn't be more appropriate here
return DataType.INTEGER;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Converts an int ASCII code to a character value.
*/
public class Char extends UnaryStringIntFunction {

public Char(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<Char> info() {
return NodeInfo.create(this, Char::new, field());
}

@Override
protected Char replaceChild(Expression newChild) {
return new Char(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.CHAR;
}

@Override
public DataType dataType() {
return DataType.KEYWORD;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Returns the length (in characters) of the string expression.
*/
public class CharLength extends UnaryStringFunction {

public CharLength(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<CharLength> info() {
return NodeInfo.create(this, CharLength::new, field());
}

@Override
protected CharLength replaceChild(Expression newChild) {
return new CharLength(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.CHAR_LENGTH;
}

@Override
public DataType dataType() {
return DataType.INTEGER;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Lowercases all uppercase letters in a string.
*/
public class LCase extends UnaryStringFunction {

public LCase(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<LCase> info() {
return NodeInfo.create(this, LCase::new, field());
}

@Override
protected LCase replaceChild(Expression newChild) {
return new LCase(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.LCASE;
}

@Override
public DataType dataType() {
return DataType.KEYWORD;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Trims the leading whitespaces.
*/
public class LTrim extends UnaryStringFunction {

public LTrim(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<LTrim> info() {
return NodeInfo.create(this, LTrim::new, field());
}

@Override
protected LTrim replaceChild(Expression newChild) {
return new LTrim(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.LTRIM;
}

@Override
public DataType dataType() {
return DataType.KEYWORD;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.string;

import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.type.DataType;

/**
* Returns the length (number of characters) in a string, excluding the trailing blanks.
*/
public class Length extends UnaryStringFunction {

public Length(Location location, Expression field) {
super(location, field);
}

@Override
protected NodeInfo<Length> info() {
return NodeInfo.create(this, Length::new, field());
}

@Override
protected Length replaceChild(Expression newChild) {
return new Length(location(), newChild);
}

@Override
protected StringOperation operation() {
return StringOperation.LENGTH;
}

@Override
public DataType dataType() {
return DataType.INTEGER;
}

}
Loading

0 comments on commit edf83c1

Please sign in to comment.