From 900fb0aee0b68cbb88f578f20019738b4416f436 Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Mon, 4 Nov 2019 10:27:29 +0100 Subject: Add query language interpreter code --- .../edu/mimuw/cloudatlas/interpreter/Result.java | 265 +++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java (limited to 'src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java new file mode 100644 index 0000000..5afbe65 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2014, University of Warsaw + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package pl.edu.mimuw.cloudatlas.interpreter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import pl.edu.mimuw.cloudatlas.model.Type; +import pl.edu.mimuw.cloudatlas.model.TypeCollection; +import pl.edu.mimuw.cloudatlas.model.Value; +import pl.edu.mimuw.cloudatlas.model.ValueList; + +abstract class Result { + public interface BinaryOperation { + public Value perform(Value v1, Value v2); + } + + public interface UnaryOperation { + public Value perform(Value v); + } + + public interface AggregationOperation { + public Value perform(ValueList values); + } + + public interface TransformOperation { + public ValueList perform(ValueList values); + } + + private static final BinaryOperation IS_EQUAL = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.isEqual(v2); + } + }; + + private static final BinaryOperation IS_LOWER_THAN = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.isLowerThan(v2); + } + }; + + private static final BinaryOperation ADD_VALUE = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.addValue(v2); + } + }; + + private static final BinaryOperation SUBTRACT = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.subtract(v2); + } + }; + + private static final BinaryOperation MULTIPLY = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.multiply(v2); + } + }; + + private static final BinaryOperation DIVIDE = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.divide(v2); + } + }; + + private static final BinaryOperation MODULO = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.modulo(v2); + } + }; + + private static final BinaryOperation AND = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.and(v2); + } + }; + + private static final BinaryOperation OR = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.or(v2); + } + }; + + private static final BinaryOperation REG_EXPR = new BinaryOperation() { + @Override + public Value perform(Value v1, Value v2) { + return v1.regExpr(v2); + } + }; + + private static final UnaryOperation NEGATE = new UnaryOperation() { + @Override + public Value perform(Value v) { + return v.negate(); + } + }; + + private static final UnaryOperation VALUE_SIZE = new UnaryOperation() { + @Override + public Value perform(Value v) { + return v.valueSize(); + } + }; + + protected abstract Result binaryOperationTyped(BinaryOperation operation, ResultSingle right); + + public Result binaryOperation(BinaryOperation operation, Result right) { + return right.callMe(operation, this); + } + + public abstract Result unaryOperation(UnaryOperation operation); + + protected abstract Result callMe(BinaryOperation operation, Result left); + + public abstract Value getValue(); + + public abstract ValueList getList(); + + public abstract ValueList getColumn(); + + public ResultSingle aggregationOperation(AggregationOperation operation) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Result transformOperation(TransformOperation operation) { + // TODO + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Result isEqual(Result right) { + return right.callMe(IS_EQUAL, this); + } + + public Result isLowerThan(Result right) { + return right.callMe(IS_LOWER_THAN, this); + } + + public Result addValue(Result right) { + return right.callMe(ADD_VALUE, this); + } + + public Result subtract(Result right) { + return right.callMe(SUBTRACT, this); + } + + public Result multiply(Result right) { + return right.callMe(MULTIPLY, this); + } + + public Result divide(Result right) { + return right.callMe(DIVIDE, this); + } + + public Result modulo(Result right) { + return right.callMe(MODULO, this); + } + + public Result and(Result right) { + return right.callMe(AND, this); + } + + public Result or(Result right) { + return right.callMe(OR, this); + } + + public Result regExpr(Result right) { + return right.callMe(REG_EXPR, this); + } + + public Result negate() { + return unaryOperation(NEGATE); + } + + public Result valueSize() { + return unaryOperation(VALUE_SIZE); + } + + protected static ValueList filterNullsList(ValueList list) { + List result = new ArrayList(); + if(list.isEmpty()) + return new ValueList(result, ((TypeCollection)list.getType()).getElementType()); + for(Value v : list) + if(!v.isNull()) + result.add(v); + return new ValueList(result.isEmpty()? null : result, ((TypeCollection)list.getType()).getElementType()); + } + + public abstract Result filterNulls(); + + protected static ValueList firstList(ValueList list, int size) { + ValueList nlist = filterNullsList(list); + if(nlist.getValue() == null) + return nlist; + List result = new ArrayList(size); + int i = 0; + for(Value v : nlist) { + result.add(v); + if(++i == size) + break; + } + return new ValueList(result, ((TypeCollection)list.getType()).getElementType()); + } + + public abstract Result first(int size); + + protected static ValueList lastList(ValueList list, int size) { + ValueList nlist = filterNullsList(list); + if(nlist.getValue() == null) + return nlist; + List result = new ArrayList(size); + for(int i = Math.max(0, list.size() - size); i < list.size(); ++i) + result.add(list.get(i)); + return new ValueList(result, ((TypeCollection)list.getType()).getElementType()); + } + + public abstract Result last(int size); + + protected static ValueList randomList(ValueList list, int size) { + ValueList nlist = filterNullsList(list); + if(nlist.getValue() == null || list.size() <= size) + return nlist; + Collections.shuffle(nlist); + return new ValueList(nlist.getValue().subList(0, size), ((TypeCollection)list.getType()).getElementType()); + } + + public abstract Result random(int size); + + public abstract Result convertTo(Type to); + + public abstract ResultSingle isNull(); + + public abstract Type getType(); +} -- cgit v1.2.3