OmniSciDB  ab4938a6a3
ExtensionFunctionSignatureParser.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.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.io.StringReader;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
38  final static Logger MAPDLOGGER =
39  LoggerFactory.getLogger(ExtensionFunctionSignatureParser.class);
40 
41  static Map<String, ExtensionFunction> parse(final String file_path) throws IOException {
42  File file = new File(file_path);
43  FileReader fileReader = new FileReader(file);
44  BufferedReader bufferedReader = new BufferedReader(fileReader);
45  String line;
46  Pattern s = Pattern.compile("\\| ([\\` ]|used)+ ([\\w]+) '([\\w<>]+) \\((.*)\\)'");
47  Map<String, ExtensionFunction> sigs = new HashMap<String, ExtensionFunction>();
48  while ((line = bufferedReader.readLine()) != null) {
49  Matcher m = s.matcher(line);
50  if (m.find()) {
51  final String name = m.group(2);
52  final String ret = m.group(3);
53  final String cs_param_list = m.group(4);
54  sigs.put(name, toSignature(ret, cs_param_list, false));
55  }
56  }
57  return sigs;
58  }
59 
60  static Map<String, ExtensionFunction> parseUdfAst(final String file_path)
61  throws IOException {
62  File file = new File(file_path);
63  FileReader fileReader = new FileReader(file);
64  BufferedReader bufferedReader = new BufferedReader(fileReader);
65  String line;
66  Pattern s = Pattern.compile("([<>:\\w]+) ([:\\w]+)(?:\\(\\))?\\((.*)\\)");
67  Map<String, ExtensionFunction> sigs = new HashMap<String, ExtensionFunction>();
68  while ((line = bufferedReader.readLine()) != null) {
69  Matcher m = s.matcher(line);
70  if (m.find()) {
71  final String name = m.group(2);
72  final String ret = m.group(1);
73  final String cs_param_list = m.group(3);
74  if (cs_param_list.isEmpty()) {
75  continue;
76  }
77  sigs.put(name, toSignature(ret, cs_param_list, true));
78  }
79  }
80  return sigs;
81  }
82 
83  static Map<String, ExtensionFunction> parseFromString(final String udf_string)
84  throws IOException {
85  return parseFromString(udf_string, true);
86  }
87 
88  static Map<String, ExtensionFunction> parseFromString(
89  final String udf_string, final boolean is_row_func) throws IOException {
90  StringReader stringReader = new StringReader(udf_string);
91  BufferedReader bufferedReader = new BufferedReader(stringReader);
92  String line;
93  Pattern r = Pattern.compile("([\\w]+)\\s+'([\\w]+)\\s*\\((.*)\\)'");
94  Map<String, ExtensionFunction> sigs = new HashMap<String, ExtensionFunction>();
95  while ((line = bufferedReader.readLine()) != null) {
96  Matcher m = r.matcher(line);
97  if (m.find()) {
98  final String name = m.group(1);
99  final String ret = m.group(2);
100  final String cs_param_list = m.group(3);
101  sigs.put(name, toSignature(ret, cs_param_list, is_row_func));
102  }
103  }
104  return sigs;
105  }
106  static String signaturesToJson(final Map<String, ExtensionFunction> sigs) {
107  List<String> json_sigs = new ArrayList<String>();
108  if (sigs != null) {
109  for (Map.Entry<String, ExtensionFunction> sig : sigs.entrySet()) {
110  json_sigs.add(sig.getValue().toJson(sig.getKey()));
111  }
112  }
113  return "[" + join(json_sigs, ",") + "]";
114  }
115 
117  final String ret, final String cs_param_list, final boolean has_variable_name) {
118  return toSignature(ret, cs_param_list, has_variable_name, true);
119  }
120 
121  private static ExtensionFunction toSignature(final String ret,
122  final String cs_param_list,
123  final boolean has_variable_name,
124  final boolean is_row_func) {
125  String[] params = cs_param_list.split(",");
127  new ArrayList<ExtensionFunction.ExtArgumentType>();
128  for (final String param : params) {
130  if (has_variable_name) {
131  String[] full_param = param.trim().split("\\s+");
132  if (full_param.length > 0) {
133  if (full_param[0].trim().compareTo("const") == 0) {
134  assert full_param.length > 1;
135  arg_type = deserializeType((full_param[1]).trim());
136  } else {
137  arg_type = deserializeType((full_param[0]).trim());
138  }
139  } else {
140  arg_type = deserializeType(full_param[0]);
141  }
142  } else {
143  arg_type = deserializeType(param.trim());
144  }
145  if (arg_type != ExtensionFunction.ExtArgumentType.Void) {
146  args.add(arg_type);
147  }
148  }
149  return new ExtensionFunction(args, deserializeType(ret), is_row_func);
150  }
152  final String type_name) {
153  final String const_prefix = "const ";
154  final String std_namespace_prefix = "std::";
155 
156  if (type_name.startsWith(const_prefix)) {
157  return deserializeType(type_name.substring(const_prefix.length()));
158  }
159  if (type_name.startsWith(std_namespace_prefix)) {
160  return deserializeType(type_name.substring(std_namespace_prefix.length()));
161  }
162 
163  if (type_name.equals("bool") || type_name.equals("_Bool")) {
165  }
166  if (type_name.equals("int8_t") || type_name.equals("char")
167  || type_name.equals("int8")) {
169  }
170  if (type_name.equals("int16_t") || type_name.equals("short")
171  || type_name.equals("int16")) {
173  }
174  if (type_name.equals("int32_t") || type_name.equals("int")
175  || type_name.equals("int32")) {
177  }
178  if (type_name.equals("int64_t") || type_name.equals("size_t")
179  || type_name.equals("int64") || type_name.equals("long")) {
181  }
182  if (type_name.equals("float") || type_name.equals("float32")) {
184  }
185  if (type_name.equals("double") || type_name.equals("float64")) {
187  }
188  if (type_name.isEmpty() || type_name.equals("void")) {
190  }
191  if (type_name.endsWith(" *")) {
192  return pointerType(deserializeType(type_name.substring(0, type_name.length() - 2)));
193  }
194  if (type_name.endsWith("*")) {
195  return pointerType(deserializeType(type_name.substring(0, type_name.length() - 1)));
196  }
197  if (type_name.equals("Array<bool>")) {
199  }
200  if (type_name.equals("Array<int8_t>") || type_name.equals("Array<char>")) {
202  }
203  if (type_name.equals("Array<int16_t>") || type_name.equals("Array<short>")) {
205  }
206  if (type_name.equals("Array<int32_t>") || type_name.equals("Array<int>")) {
208  }
209  if (type_name.equals("Array<int64_t>") || type_name.equals("Array<size_t>")
210  || type_name.equals("Array<long>")) {
212  }
213  if (type_name.equals("Array<float>")) {
215  }
216  if (type_name.equals("Array<double>")) {
218  }
219  if (type_name.equals("Cursor")) {
221  }
222  if (type_name.equals("GeoPoint")) {
224  }
225  if (type_name.equals("GeoLineString")) {
227  }
228  if (type_name.equals("GeoPolygon")) {
230  }
231  if (type_name.equals("GeoMultiPolygon")) {
233  }
234 
235  MAPDLOGGER.info(
236  "ExtensionfunctionSignatureParser::deserializeType: unknown type_name=`"
237  + type_name + "`");
238  // TODO: Return void for convenience. Consider sanitizing functions for supported
239  // types before they reach Calcite
241  }
242 
244  final ExtensionFunction.ExtArgumentType targetType) {
245  switch (targetType) {
246  case Bool:
248  case Int8:
250  case Int16:
252  case Int32:
254  case Int64:
256  case Float:
258  case Double:
260  default:
261  assert false;
262  return null;
263  }
264  }
265 
266  static String join(final List<String> strs, final String sep) {
267  StringBuilder sb = new StringBuilder();
268  if (strs.isEmpty()) {
269  return "";
270  }
271  sb.append(strs.get(0));
272  for (int i = 1; i < strs.size(); ++i) {
273  sb.append(sep).append(strs.get(i));
274  }
275  return sb.toString();
276  }
277 }
static Map< String, ExtensionFunction > parseFromString(final String udf_string)
static ExtensionFunction.ExtArgumentType pointerType(final ExtensionFunction.ExtArgumentType targetType)
static Map< String, ExtensionFunction > parseFromString(final String udf_string, final boolean is_row_func)
static ExtensionFunction toSignature(final String ret, final String cs_param_list, final boolean has_variable_name, final boolean is_row_func)
static Map< String, ExtensionFunction > parse(final String file_path)
static String join(final List< String > strs, final String sep)
static ExtensionFunction toSignature(final String ret, final String cs_param_list, final boolean has_variable_name)
static String signaturesToJson(final Map< String, ExtensionFunction > sigs)
static ExtensionFunction.ExtArgumentType deserializeType(final String type_name)
static Map< String, ExtensionFunction > parseUdfAst(final String file_path)