OmniSciDB  6686921089
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExtensionFunction.java
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.mapd.parser.server;
17 
18 import org.apache.calcite.sql.type.SqlTypeFamily;
19 import org.apache.calcite.sql.type.SqlTypeName;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 
23 import java.util.ArrayList;
24 import java.util.EnumSet;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 
34 public class ExtensionFunction {
35  final static Logger MAPDLOGGER = LoggerFactory.getLogger(ExtensionFunction.class);
36 
37  public enum ExtArgumentType {
83  }
84  ;
85 
86  ExtensionFunction(final List<ExtArgumentType> args, final ExtArgumentType ret) {
87  this.args = args;
88  this.ret = ret;
89  this.outs = null;
90  this.names = null;
91  this.isRowUdf = true;
92  this.options = null;
93  }
94 
95  ExtensionFunction(final List<ExtArgumentType> args,
96  final List<ExtArgumentType> outs,
97  final List<String> names,
98  final Map<String, String> options) {
99  this.args = args;
100  this.ret = null;
101  this.outs = outs;
102  this.names = names;
103  this.isRowUdf = false;
104  this.options = options;
105  }
106 
107  public List<ExtArgumentType> getArgs() {
108  return this.args;
109  }
110 
111  public List<ExtArgumentType> getOuts() {
112  return this.outs;
113  }
114 
115  public List<String> getArgNames() {
116  if (this.names != null) {
117  return this.names.subList(0, this.args.size());
118  }
119  return null;
120  }
121 
122  public List<String> getOutNames() {
123  if (this.names != null) {
124  return this.names.subList(this.args.size(), this.names.size());
125  }
126  return null;
127  }
128 
130  return this.ret;
131  }
132 
133  public SqlTypeName getSqlRet() {
134  assert this.isRowUdf();
135  return toSqlTypeName(this.ret);
136  }
137 
138  public List<SqlTypeName> getSqlOuts() {
139  assert this.isTableUdf();
140  List<SqlTypeName> sql_outs = new ArrayList<SqlTypeName>();
141  for (final ExtArgumentType otype : this.getOuts()) {
142  sql_outs.add(toSqlTypeName(getValueType(otype)));
143  }
144  return sql_outs;
145  }
146 
147  public Map<String, String> getOptions() {
148  if (this.options != null) {
149  return new HashMap<String, String>(this.options);
150  }
151  return null;
152  }
153 
154  public boolean isRowUdf() {
155  return this.isRowUdf;
156  }
157 
158  public boolean isTableUdf() {
159  return !this.isRowUdf();
160  }
161 
162  public String toJson(final String name) {
163  MAPDLOGGER.debug("Extensionfunction::toJson: " + name);
164  StringBuilder json_cons = new StringBuilder();
165  json_cons.append("{");
166  json_cons.append("\"name\":").append(dq(name)).append(",");
167  if (isRowUdf) {
168  json_cons.append("\"ret\":").append(dq(typeName(ret))).append(",");
169  } else {
170  json_cons.append("\"outs\":");
171  json_cons.append("[");
172  List<String> param_list = new ArrayList<String>();
173  for (final ExtArgumentType out : outs) {
174  param_list.add(dq(typeName(out)));
175  }
176  json_cons.append(ExtensionFunctionSignatureParser.join(param_list, ","));
177  json_cons.append("],");
178  }
179  json_cons.append("\"args\":");
180  json_cons.append("[");
181  List<String> param_list = new ArrayList<String>();
182  for (final ExtArgumentType arg : args) {
183  param_list.add(dq(typeName(arg)));
184  }
185  json_cons.append(ExtensionFunctionSignatureParser.join(param_list, ","));
186  json_cons.append("]");
187  json_cons.append("}");
188  return json_cons.toString();
189  }
190 
191  private static String typeName(final ExtArgumentType type) {
192  switch (type) {
193  case Bool:
194  return "i1";
195  case Int8:
196  return "i8";
197  case Int16:
198  return "i16";
199  case Int32:
200  return "i32";
201  case Int64:
202  return "i64";
203  case Float:
204  return "float";
205  case Double:
206  return "double";
207  case Void:
208  return "void";
209  case PInt8:
210  return "i8*";
211  case PInt16:
212  return "i16*";
213  case PInt32:
214  return "i32*";
215  case PInt64:
216  return "i64*";
217  case PFloat:
218  return "float*";
219  case PDouble:
220  return "double*";
221  case PBool:
222  return "i1*";
223  case ArrayInt8:
224  return "{i8*, i64, i8}*";
225  case ArrayInt16:
226  return "{i16*, i64, i8}*";
227  case ArrayInt32:
228  return "{i32*, i64, i8}*";
229  case ArrayInt64:
230  return "{i64*, i64, i8}*";
231  case ArrayFloat:
232  return "{float*, i64, i8}*";
233  case ArrayDouble:
234  return "{double*, i64, i8}*";
235  case ArrayBool:
236  return "{i1*, i64, i8}*";
237  case ColumnInt8:
238  return "column_int8";
239  case ColumnInt16:
240  return "column_int16";
241  case ColumnInt32:
242  return "column_int32";
243  case ColumnInt64:
244  return "column_int64";
245  case ColumnFloat:
246  return "column_float";
247  case ColumnDouble:
248  return "column_double";
249  case ColumnBool:
250  return "column_bool";
252  return "column_text_encoding_dict";
253  case GeoPoint:
254  return "geo_point";
255  case Cursor:
256  return "cursor";
257  case GeoLineString:
258  return "geo_linestring";
259  case GeoPolygon:
260  return "geo_polygon";
261  case GeoMultiPolygon:
262  return "geo_multi_polygon";
263  case TextEncodingNone:
264  return "text_encoding_none";
265  case TextEncodingDict:
266  return "text_encoding_dict";
267  case ColumnListInt8:
268  return "column_list_int8";
269  case ColumnListInt16:
270  return "column_list_int16";
271  case ColumnListInt32:
272  return "column_list_int32";
273  case ColumnListInt64:
274  return "column_list_int64";
275  case ColumnListFloat:
276  return "column_list_float";
277  case ColumnListDouble:
278  return "column_list_double";
279  case ColumnListBool:
280  return "column_list_bool";
282  return "column_list_text_encoding_dict";
283  }
284  MAPDLOGGER.info("Extensionfunction::typeName: unknown type=`" + type + "`");
285  assert false;
286  return null;
287  }
288 
289  private static String dq(final String str) {
290  return "\"" + str + "\"";
291  }
292 
293  private final List<ExtArgumentType> args;
294  private final List<ExtArgumentType> outs; // only used by UDTFs
295  private final List<String> names;
296  private final ExtArgumentType ret; // only used by UDFs
297  private final boolean isRowUdf;
298  private final Map<String, String> options;
299 
300  public final java.util.List<SqlTypeFamily> toSqlSignature() {
301  java.util.List<SqlTypeFamily> sql_sig = new java.util.ArrayList<SqlTypeFamily>();
302  boolean isRowUdf = this.isRowUdf();
303  for (int arg_idx = 0; arg_idx < this.getArgs().size(); ++arg_idx) {
304  final ExtArgumentType arg_type = this.getArgs().get(arg_idx);
305  if (isRowUdf) {
306  sql_sig.add(toSqlTypeName(arg_type).getFamily());
307  if (isPointerType(arg_type)) {
308  ++arg_idx;
309  }
310  } else {
311  sql_sig.add(toSqlTypeName(arg_type).getFamily());
312  }
313  }
314  return sql_sig;
315  }
316 
317  private static boolean isPointerType(final ExtArgumentType type) {
318  return type == ExtArgumentType.PInt8 || type == ExtArgumentType.PInt16
319  || type == ExtArgumentType.PInt32 || type == ExtArgumentType.PInt64
320  || type == ExtArgumentType.PFloat || type == ExtArgumentType.PDouble
321  || type == ExtArgumentType.PBool;
322  }
323 
324  private static boolean isColumnType(final ExtArgumentType type) {
325  return type == ExtArgumentType.ColumnInt8 || type == ExtArgumentType.ColumnInt16
326  || type == ExtArgumentType.ColumnInt32 || type == ExtArgumentType.ColumnInt64
327  || type == ExtArgumentType.ColumnFloat || type == ExtArgumentType.ColumnDouble
328  || type == ExtArgumentType.ColumnBool
330  }
331 
332  private static boolean isColumnListType(final ExtArgumentType type) {
333  return type == ExtArgumentType.ColumnListInt8
334  || type == ExtArgumentType.ColumnListInt16
335  || type == ExtArgumentType.ColumnListInt32
336  || type == ExtArgumentType.ColumnListInt64
337  || type == ExtArgumentType.ColumnListFloat
338  || type == ExtArgumentType.ColumnListDouble
339  || type == ExtArgumentType.ColumnListBool
341  }
342 
344  switch (type) {
345  case PInt8:
346  case ColumnInt8:
347  case ColumnListInt8:
348  case Int8:
349  return ExtArgumentType.Int8;
350  case PInt16:
351  case ColumnInt16:
352  case ColumnListInt16:
353  case Int16:
354  return ExtArgumentType.Int16;
355  case PInt32:
356  case ColumnInt32:
357  case ColumnListInt32:
358  case Int32:
359  return ExtArgumentType.Int32;
360  case PInt64:
361  case ColumnInt64:
362  case ColumnListInt64:
363  case Int64:
364  return ExtArgumentType.Int64;
365  case PFloat:
366  case ColumnFloat:
367  case ColumnListFloat:
368  case Float:
369  return ExtArgumentType.Float;
370  case PDouble:
371  case ColumnDouble:
372  case ColumnListDouble:
373  case Double:
374  return ExtArgumentType.Double;
375  case PBool:
376  case ColumnBool:
377  case ColumnListBool:
378  case Bool:
379  return ExtArgumentType.Bool;
380  case TextEncodingDict:
384  }
385  MAPDLOGGER.error("getValueType: no value for type " + type);
386  assert false;
387  return null;
388  }
389 
390  private static SqlTypeName toSqlTypeName(final ExtArgumentType type) {
391  switch (type) {
392  case Bool:
393  return SqlTypeName.BOOLEAN;
394  case Int8:
395  return SqlTypeName.TINYINT;
396  case Int16:
397  return SqlTypeName.SMALLINT;
398  case Int32:
399  return SqlTypeName.INTEGER;
400  case Int64:
401  return SqlTypeName.BIGINT;
402  case Float:
403  return SqlTypeName.FLOAT;
404  case Double:
405  return SqlTypeName.DOUBLE;
406  case PInt8:
407  case PInt16:
408  case PInt32:
409  case PInt64:
410  case PFloat:
411  case PDouble:
412  case PBool:
413  case ArrayInt8:
414  case ArrayInt16:
415  case ArrayInt32:
416  case ArrayInt64:
417  case ArrayFloat:
418  case ArrayDouble:
419  case ArrayBool:
420  return SqlTypeName.ARRAY;
421  case GeoPoint:
422  case GeoLineString:
423  case GeoPolygon:
424  case GeoMultiPolygon:
425  return SqlTypeName.GEOMETRY;
426  case Cursor:
427  return SqlTypeName.CURSOR;
428  case TextEncodingNone:
429  case TextEncodingDict:
430  return SqlTypeName.VARCHAR;
431  case ColumnListInt8:
432  case ColumnListInt16:
433  case ColumnListInt32:
434  case ColumnListInt64:
435  case ColumnListFloat:
436  case ColumnListDouble:
437  case ColumnListBool:
439  return SqlTypeName.COLUMN_LIST;
440  case Void:
441  // some extension functions return void. these functions should be defined in
442  // MapDSqlOperatorTable and never have their definition set from the AST file
443  return null;
444  }
445  Set<SqlTypeName> allSqlTypeNames = EnumSet.allOf(SqlTypeName.class);
446  MAPDLOGGER.error("toSqlTypeName: unknown type " + type + " to be mapped to {"
447  + allSqlTypeNames + "}");
448  assert false;
449  return null;
450  }
451 }
final java.util.List< SqlTypeFamily > toSqlSignature()
size_t append(FILE *f, const size_t size, const int8_t *buf)
Appends the specified number of bytes to the end of the file f from buf.
Definition: File.cpp:159
static SqlTypeName toSqlTypeName(final ExtArgumentType type)
#define GEOMETRY
#define CURSOR
Simplified core of GeoJSON Polygon coordinates definition.
Definition: OmniSciTypes.h:149
#define SMALLINT
ExtensionFunction(final List< ExtArgumentType > args, final List< ExtArgumentType > outs, final List< String > names, final Map< String, String > options)
#define DOUBLE
string name
Definition: setup.in.py:72
#define BIGINT
Simplified core of GeoJSON MultiPolygon coordinates definition.
Definition: OmniSciTypes.h:170
static boolean isColumnListType(final ExtArgumentType type)
static boolean isColumnType(final ExtArgumentType type)
#define TINYINT
#define ARRAY
ExtensionFunction(final List< ExtArgumentType > args, final ExtArgumentType ret)
static String typeName(final ExtArgumentType type)
static String dq(final String str)
#define FLOAT
static boolean isPointerType(final ExtArgumentType type)
static ExtArgumentType getValueType(final ExtArgumentType type)
#define BOOLEAN
#define INTEGER