From bd533f401029d3e535f9295d5c0e990493371396 Mon Sep 17 00:00:00 2001 From: bluestreak02 Date: Thu, 11 Jul 2019 23:39:55 +0100 Subject: [PATCH] GRIFFIN: "case" implementation for strings - in a hurry to support client tomorrow. This only manually tested. Unit tests to follow. --- .../conditional/CaseFunctionFactory.java | 116 ++++++++++++++++++ .../com.questdb.griffin.FunctionFactory | 71 +---------- 2 files changed, 118 insertions(+), 69 deletions(-) create mode 100644 core/src/main/java/com/questdb/griffin/engine/functions/conditional/CaseFunctionFactory.java diff --git a/core/src/main/java/com/questdb/griffin/engine/functions/conditional/CaseFunctionFactory.java b/core/src/main/java/com/questdb/griffin/engine/functions/conditional/CaseFunctionFactory.java new file mode 100644 index 000000000..d321f3d5b --- /dev/null +++ b/core/src/main/java/com/questdb/griffin/engine/functions/conditional/CaseFunctionFactory.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * ___ _ ____ ____ + * / _ \ _ _ ___ ___| |_| _ \| __ ) + * | | | | | | |/ _ \/ __| __| | | | _ \ + * | |_| | |_| | __/\__ \ |_| |_| | |_) | + * \__\_\\__,_|\___||___/\__|____/|____/ + * + * Copyright (C) 2014-2019 Appsicle + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + ******************************************************************************/ + +package com.questdb.griffin.engine.functions.conditional; + +import com.questdb.cairo.CairoConfiguration; +import com.questdb.cairo.ColumnType; +import com.questdb.cairo.sql.Function; +import com.questdb.cairo.sql.Record; +import com.questdb.griffin.FunctionFactory; +import com.questdb.griffin.SqlException; +import com.questdb.griffin.engine.functions.StrFunction; +import com.questdb.std.ObjList; + +public class CaseFunctionFactory implements FunctionFactory { + @Override + public String getSignature() { + return "case(V)"; + } + + @Override + //todo: unit test this and add support for all types + public Function newInstance(ObjList args, int position, CairoConfiguration configuration) throws SqlException { + int n = args.size(); + int returnType = -1; + final ObjList vars = new ObjList<>(n); + + Function elseBranch; + if (n % 2 == 1) { + elseBranch = args.getQuick(n - 1); + n--; + } else { + elseBranch = null; + } + + + for (int i = 0; i < n; i += 2) { + Function bool = args.getQuick(i); + Function outcome = args.getQuick(i + 1); + + if (bool.getType() != ColumnType.BOOLEAN) { + throw SqlException.position(bool.getPosition()).put("BOOLEAN expected, found ").put(ColumnType.nameOf(bool.getType())); + } + + if (i == 0) { + returnType = outcome.getType(); + } else if (returnType != outcome.getType()) { + throw SqlException.position(outcome.getPosition()).put(ColumnType.nameOf(returnType)).put(" expected, found ").put(ColumnType.nameOf(outcome.getType())); + } + + vars.add(bool); + vars.add(outcome); + } + + switch (returnType) { + case ColumnType.STRING: + return new StrCaseFunction(position, vars, elseBranch); + default: + throw SqlException.$(position, "not implemented for type '").put(ColumnType.nameOf(returnType)).put('\''); + + } + } + + private static class StrCaseFunction extends StrFunction { + private final ObjList args; + private final int argsLen; + private final Function elseBranch; + + public StrCaseFunction(int position, ObjList args, Function elseBranch) { + super(position); + this.args = args; + this.argsLen = args.size(); + this.elseBranch = elseBranch; + } + + @Override + public CharSequence getStr(Record rec) { + for (int i = 0; i < argsLen; i += 2) { + if (args.getQuick(i).getBool(rec)) { + return args.getQuick(i + 1).getStr(rec); + } + } + return elseBranch == null ? null : elseBranch.getStr(rec); + } + + @Override + public CharSequence getStrB(Record rec) { + for (int i = 0; i < argsLen; i += 2) { + if (args.getQuick(i).getBool(rec)) { + return args.getQuick(i + 1).getStrB(rec); + } + } + return elseBranch.getStrB(rec); + } + } +} diff --git a/core/src/main/resources/META-INF/services/com.questdb.griffin.FunctionFactory b/core/src/main/resources/META-INF/services/com.questdb.griffin.FunctionFactory index 534c5b5f6..65eafd0b9 100644 --- a/core/src/main/resources/META-INF/services/com.questdb.griffin.FunctionFactory +++ b/core/src/main/resources/META-INF/services/com.questdb.griffin.FunctionFactory @@ -1,72 +1,3 @@ -################################################################################ -# ___ _ ____ ____ -# / _ \ _ _ ___ ___| |_| _ \| __ ) -# | | | | | | |/ _ \/ __| __| | | | _ \ -# | |_| | |_| | __/\__ \ |_| |_| | |_) | -# \__\_\\__,_|\___||___/\__|____/|____/ -# -# Copyright (C) 2014-2018 Appsicle -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3, -# as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -################################################################################ - -################################################################################ -# ___ _ ____ ____ -# / _ \ _ _ ___ ___| |_| _ \| __ ) -# | | | | | | |/ _ \/ __| __| | | | _ \ -# | |_| | |_| | __/\__ \ |_| |_| | |_) | -# \__\_\\__,_|\___||___/\__|____/|____/ -# -# Copyright (C) 2014-2018 Appsicle -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3, -# as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -################################################################################ - -################################################################################ -# ___ _ ____ ____ -# / _ \ _ _ ___ ___| |_| _ \| __ ) -# | | | | | | |/ _ \/ __| __| | | | _ \ -# | |_| | |_| | __/\__ \ |_| |_| | |_) | -# \__\_\\__,_|\___||___/\__|____/|____/ -# -# Copyright (C) 2014-2018 Appsicle -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3, -# as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -################################################################################ - # logical operations com.questdb.griffin.engine.functions.bool.OrFunctionFactory com.questdb.griffin.engine.functions.bool.AndFunctionFactory @@ -184,3 +115,5 @@ com.questdb.griffin.engine.functions.groupby.CountGroupByFunctionFactory # round() com.questdb.griffin.engine.functions.math.RoundDoubleFunctionFactory +# case conditional statement +com.questdb.griffin.engine.functions.conditional.CaseFunctionFactory \ No newline at end of file -- GitLab