From 8d2fd7aacc4b73632f3aa976d7e453cf1cae3a77 Mon Sep 17 00:00:00 2001 From: Andy Yang Date: Fri, 23 Mar 2018 17:31:33 +0800 Subject: [PATCH] [JIRA 3008] support a new TMUDF to generate a series of Number --- core/sql/common/ExprNode.cpp | 10 ++- core/sql/common/OperTypeEnum.h | 1 + core/sql/generator/GenShape.cpp | 1 + core/sql/nskgmake/udr_predef/Makefile | 1 + core/sql/optimizer/RelRoutine.cpp | 9 ++ core/sql/sqludr/SqlUdrPredefSeries.cpp | 112 +++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 core/sql/sqludr/SqlUdrPredefSeries.cpp diff --git a/core/sql/common/ExprNode.cpp b/core/sql/common/ExprNode.cpp index 80d91a1bee..2c128985b1 100644 --- a/core/sql/common/ExprNode.cpp +++ b/core/sql/common/ExprNode.cpp @@ -181,8 +181,9 @@ NABoolean OperatorType::match(OperatorTypeEnum wildcard) const case REL_UNARY_TABLE_MAPPING_UDF: case REL_BINARY_TABLE_MAPPING_UDF: case REL_TABLE_MAPPING_BUILTIN_LOG_READER: - case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: - case REL_TABLE_MAPPING_BUILTIN_JDBC: + case REL_TABLE_MAPPING_BUILTIN_SERIES: + case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: + case REL_TABLE_MAPPING_BUILTIN_JDBC: return TRUE; default: return FALSE; @@ -700,8 +701,9 @@ NABoolean OperatorType::match(OperatorTypeEnum wildcard) const case REL_UNARY_TABLE_MAPPING_UDF: case REL_BINARY_TABLE_MAPPING_UDF: case REL_TABLE_MAPPING_BUILTIN_LOG_READER: - case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: - case REL_TABLE_MAPPING_BUILTIN_JDBC: + case REL_TABLE_MAPPING_BUILTIN_SERIES: + case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: + case REL_TABLE_MAPPING_BUILTIN_JDBC: return TRUE; default: return FALSE; diff --git a/core/sql/common/OperTypeEnum.h b/core/sql/common/OperTypeEnum.h index c70310f873..ee84c80a9f 100644 --- a/core/sql/common/OperTypeEnum.h +++ b/core/sql/common/OperTypeEnum.h @@ -94,6 +94,7 @@ enum OperatorTypeEnum { REL_BINARY_TABLE_MAPPING_UDF, REL_TABLE_MAPPING_BUILTIN_LOG_READER, REL_TABLE_MAPPING_BUILTIN_TIMESERIES, + REL_TABLE_MAPPING_BUILTIN_SERIES, //series REL_TABLE_MAPPING_BUILTIN_JDBC, REL_ANY_TABLE_MAPPING_UDF, REL_ANY_LEAF_TABLE_MAPPING_UDF, diff --git a/core/sql/generator/GenShape.cpp b/core/sql/generator/GenShape.cpp index 420d9a2e29..0f59c94575 100644 --- a/core/sql/generator/GenShape.cpp +++ b/core/sql/generator/GenShape.cpp @@ -128,6 +128,7 @@ short RelExpr::generateShape(CollHeap * c, char * buf, NAString * shapeStr) case REL_UNARY_TABLE_MAPPING_UDF: case REL_BINARY_TABLE_MAPPING_UDF: case REL_TABLE_MAPPING_BUILTIN_LOG_READER: + case REL_TABLE_MAPPING_BUILTIN_SERIES: case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: case REL_TABLE_MAPPING_BUILTIN_JDBC: { diff --git a/core/sql/nskgmake/udr_predef/Makefile b/core/sql/nskgmake/udr_predef/Makefile index ac6b588b07..3e287293fc 100755 --- a/core/sql/nskgmake/udr_predef/Makefile +++ b/core/sql/nskgmake/udr_predef/Makefile @@ -25,6 +25,7 @@ SRCPATH := sqludr CPPSRC := SqlUdrPredefLogReader.cpp \ SqlUdrPredefTimeSeries.cpp \ + SqlUdrPredefSeries.cpp \ vers_libudr_predef.cpp # Define the correct compilation and linking flags depending on whether diff --git a/core/sql/optimizer/RelRoutine.cpp b/core/sql/optimizer/RelRoutine.cpp index 7853c79301..89b2fcaff2 100644 --- a/core/sql/optimizer/RelRoutine.cpp +++ b/core/sql/optimizer/RelRoutine.cpp @@ -1070,6 +1070,8 @@ OperatorTypeEnum PredefinedTableMappingFunction::nameIsAPredefinedTMF(const Corr return REL_TABLE_MAPPING_BUILTIN_LOG_READER; else if (funcName == "TIMESERIES") return REL_TABLE_MAPPING_BUILTIN_TIMESERIES; + else if (funcName == "SERIES") + return REL_TABLE_MAPPING_BUILTIN_SERIES; else if (funcName == "JDBC") return REL_TABLE_MAPPING_BUILTIN_JDBC; else @@ -1085,6 +1087,8 @@ const NAString PredefinedTableMappingFunction::getText() const return "event_log_reader"; case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: return "timeseries"; + case REL_TABLE_MAPPING_BUILTIN_SERIES: + return "series"; case REL_TABLE_MAPPING_BUILTIN_JDBC: return "jdbc_udf"; @@ -1143,6 +1147,11 @@ NARoutine * PredefinedTableMappingFunction::getRoutineMetadata( libraryPath += getenv("SQ_MBTYPE"); break; + case REL_TABLE_MAPPING_BUILTIN_SERIES: + externalName = "SERIES"; + libraryPath += getenv("SQ_MBTYPE"); + break; + case REL_TABLE_MAPPING_BUILTIN_TIMESERIES: externalName = "TRAF_CPP_TIMESERIES"; libraryPath += getenv("SQ_MBTYPE"); diff --git a/core/sql/sqludr/SqlUdrPredefSeries.cpp b/core/sql/sqludr/SqlUdrPredefSeries.cpp new file mode 100644 index 0000000000..096e429401 --- /dev/null +++ b/core/sql/sqludr/SqlUdrPredefSeries.cpp @@ -0,0 +1,112 @@ +// @@@ START COPYRIGHT @@@ +// +// 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. +// +// @@@ END COPYRIGHT @@@ + +#include "sqludr.h" + +using namespace tmudr; + +// sample invocation of the SERIES TMUDF: +// +// SELECT * FROM UDF(series(1, 100, 2)); +// SELECT * FROM UDF(series(100, 1, -2)); +// SELECT * FROM UDF(series(1, 100)); + +/* Step 1: derive a class from tmudr::UDR*/ + +class series : public UDR +{ +public: + // determine output columns dynamically at compile time + void describeParamsAndColumns(UDRInvocationInfo &info); + + // override the runtime method + virtual void processData(UDRInvocationInfo &info, + UDRPlanInfo &plan); +}; + +/* Step 2: Create a factory method*/ + +extern "C" UDR * SERIES() +{ + return new series(); +} + +/* Step 3: Write the actual UDF code*/ +void series::describeParamsAndColumns( + UDRInvocationInfo &info) +{ + // We always expect one input parameter + int paramCount = info.par().getNumColumns(); + if (paramCount != 2 && paramCount != 3) + throw UDRException(38001, + "Expecting two or three input parameters"); + + if (info.par().getType(0).getSQLTypeClass() != info.par().getType(1).getSQLTypeClass()) + throw UDRException(38001, + "The data type of the first two parameters should be same"); + + if (info.par().getType(0).getSQLTypeClass() != TypeInfo::NUMERIC_TYPE) + throw UDRException(38001, + "Only support to generate series for exact numerics type"); + + for (int i=0; i 0 ) + for (long i=begin; i<=end;) + { + info.out().setLong(0, i); + emitRow(info); + i += step; + } + else + for (long i=begin; i>=end;) + { + info.out().setLong(0, i); + emitRow(info); + i += step; + } +}