OmniSciDB  a5dc49c757
 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 2022 HEAVY.AI, 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 
17 package com.mapd.parser.server;
18 
19 import org.apache.calcite.avatica.util.TimeUnit;
20 import org.apache.calcite.rel.type.RelDataType;
21 import org.apache.calcite.rel.type.RelDataTypeFactory;
22 import org.apache.calcite.sql.SqlIntervalQualifier;
23 import org.apache.calcite.sql.parser.SqlParserPos;
24 import org.apache.calcite.sql.type.SqlTypeFamily;
25 import org.apache.calcite.sql.type.SqlTypeName;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 
29 import java.lang.Comparable;
30 import java.util.ArrayList;
31 import java.util.EnumSet;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 
37 public class ExtensionFunction {
38  final static Logger HEAVYDBLOGGER = LoggerFactory.getLogger(ExtensionFunction.class);
39 
40  public enum ExtArgumentType {
126  }
127  ;
128 
129  ExtensionFunction(final List<ExtArgumentType> args,
130  final ExtArgumentType ret,
131  final List<Map<String, String>> annotations) {
132  this.args = args;
133  this.ret = ret;
134  this.annotations = annotations;
135  this.outs = null;
136  this.names = null;
137  this.isRowUdf = true;
138  this.options = null;
139  this.cursor_field_types = null;
140  this.default_values = null;
141  }
142 
143  ExtensionFunction(final List<ExtArgumentType> args,
144  final List<ExtArgumentType> outs,
145  final List<String> names,
146  final Map<String, String> options,
147  final Map<String, List<ExtArgumentType>> cursor_field_types,
148  final Map<String, java.lang.Comparable<?>> default_values) {
149  this.args = args;
150  this.ret = null;
151  this.outs = outs;
152  this.names = names;
153  this.isRowUdf = false;
154  this.annotations = null;
155  this.options = options;
156  this.cursor_field_types = cursor_field_types;
157  this.default_values = default_values;
158  }
159 
160  public Map<String, Comparable<?>> getDefaultValues() {
161  assert (this.isTableUdf());
162  return this.default_values;
163  }
164 
165  public Map<String, List<ExtArgumentType>> getCursorFieldTypes() {
166  assert (this.isTableUdf());
167  return this.cursor_field_types;
168  }
169 
170  public List<ExtArgumentType> getArgs() {
171  return this.args;
172  }
173 
174  public List<ExtArgumentType> getOuts() {
175  return this.outs;
176  }
177 
178  public List<String> getArgNames() {
179  if (this.names != null) {
180  return this.names.subList(0, this.args.size());
181  }
182  return null;
183  }
184 
185  public List<String> getPrettyArgNames() {
186  if (this.names != null) {
187  List<String> pretty_names = new ArrayList<String>();
188  for (int arg_idx = 0; arg_idx < this.args.size(); ++arg_idx) {
189  // Split on first array opening bracket and take everything preceding
190  // For names without array brackets this will just be the name
191  pretty_names.add(this.names.get(arg_idx).split("\\[", 2)[0]);
192  }
193  return pretty_names;
194  }
195  return null;
196  }
197 
198  public List<String> getOutNames() {
199  if (this.names != null) {
200  return this.names.subList(this.args.size(), this.names.size());
201  }
202  return null;
203  }
204 
206  return this.ret;
207  }
208 
209  public SqlTypeName getSqlRet() {
210  assert this.isRowUdf();
211  return toSqlTypeName(this.ret);
212  }
213 
214  public Map<String, String> getOptions() {
215  if (this.options != null) {
216  return new HashMap<String, String>(this.options);
217  }
218  return null;
219  }
220 
221  public boolean isRowUdf() {
222  return this.isRowUdf;
223  }
224 
225  public boolean isTableUdf() {
226  return !this.isRowUdf();
227  }
228 
229  public String toJson(final String name) {
230  HEAVYDBLOGGER.debug("Extensionfunction::toJson: " + name);
231  StringBuilder json_cons = new StringBuilder();
232  json_cons.append("{");
233  json_cons.append("\"name\":").append(dq(name)).append(",");
234  if (isRowUdf) {
235  json_cons.append("\"annotations\":");
236  List<String> anns = new ArrayList<String>();
237  for (final Map<String, String> m : this.annotations) {
238  List<String> lst = new ArrayList<String>();
239  for (final Map.Entry<String, String> kv : m.entrySet()) {
240  lst.add("\"" + kv.getKey() + "\":\"" + kv.getValue() + "\"");
241  }
242  anns.add("{" + ExtensionFunctionSignatureParser.join(lst, ",") + "}");
243  }
244  json_cons.append("[" + ExtensionFunctionSignatureParser.join(anns, ",") + "],");
245  json_cons.append("\"ret\":").append(dq(typeName(ret))).append(",");
246  } else {
247  json_cons.append("\"outs\":");
248  json_cons.append("[");
249  List<String> param_list = new ArrayList<String>();
250  for (final ExtArgumentType out : outs) {
251  param_list.add(dq(typeName(out)));
252  }
253  json_cons.append(ExtensionFunctionSignatureParser.join(param_list, ","));
254  json_cons.append("],");
255  }
256  json_cons.append("\"args\":");
257  json_cons.append("[");
258  List<String> param_list = new ArrayList<String>();
259  for (final ExtArgumentType arg : args) {
260  param_list.add(dq(typeName(arg)));
261  }
262  json_cons.append(ExtensionFunctionSignatureParser.join(param_list, ","));
263  json_cons.append("]");
264  json_cons.append("}");
265  return json_cons.toString();
266  }
267 
268  private static String typeName(final ExtArgumentType type) {
269  switch (type) {
270  case Bool:
271  return "i1";
272  case Int8:
273  return "i8";
274  case Int16:
275  return "i16";
276  case Int32:
277  return "i32";
278  case Int64:
279  return "i64";
280  case Float:
281  return "float";
282  case Double:
283  return "double";
284  case Void:
285  return "void";
286  case PInt8:
287  return "i8*";
288  case PInt16:
289  return "i16*";
290  case PInt32:
291  return "i32*";
292  case PInt64:
293  return "i64*";
294  case PFloat:
295  return "float*";
296  case PDouble:
297  return "double*";
298  case PBool:
299  return "i1*";
300  case ArrayInt8:
301  return "Array<i8>";
302  case ArrayInt16:
303  return "Array<i16>";
304  case ArrayInt32:
305  return "Array<i32>";
306  case ArrayInt64:
307  return "Array<i64>";
308  case ArrayFloat:
309  return "Array<float>";
310  case ArrayDouble:
311  return "Array<double>";
312  case ArrayBool:
313  return "Array<bool>";
315  return "Array<TextEncodingDict>";
316  case ColumnInt8:
317  return "Column<i8>";
318  case ColumnInt16:
319  return "Column<i16>";
320  case ColumnInt32:
321  return "Column<i32>";
322  case ColumnInt64:
323  return "Column<i64>";
324  case ColumnFloat:
325  return "Column<float>";
326  case ColumnDouble:
327  return "Column<double>";
328  case ColumnBool:
329  return "Column<bool>";
331  return "Column<TextEncodingDict>";
332  case ColumnTimestamp:
333  return "Column<timestamp>";
334  case GeoPoint:
335  return "GeoPoint";
336  case GeoMultiPoint:
337  return "GeoMultiPoint";
338  case Cursor:
339  return "cursor";
340  case GeoLineString:
341  return "GeoLineString";
342  case GeoMultiLineString:
343  return "GeoMultiLineString";
344  case GeoPolygon:
345  return "GeoPolygon";
346  case GeoMultiPolygon:
347  return "GeoMultiPolygon";
348  case Timestamp:
349  return "timestamp";
350  case TextEncodingNone:
351  return "TextEncodingNone";
352  case TextEncodingDict:
353  return "TextEncodingDict";
354  case ColumnListInt8:
355  return "ColumnList<i8>";
356  case ColumnListInt16:
357  return "ColumnList<i16>";
358  case ColumnListInt32:
359  return "ColumnList<i32>";
360  case ColumnListInt64:
361  return "ColumnList<i64>";
362  case ColumnListFloat:
363  return "ColumnList<float>";
364  case ColumnListDouble:
365  return "ColumnList<double>";
366  case ColumnListBool:
367  return "ColumnList<bool>";
369  return "ColumnList<TextEncodingDict>";
370  case ColumnArrayInt8:
371  return "Column<Array<i8>>";
372  case ColumnArrayInt16:
373  return "Column<Array<i16>>";
374  case ColumnArrayInt32:
375  return "Column<Array<i32>>";
376  case ColumnArrayInt64:
377  return "Column<Array<i64>>";
378  case ColumnArrayFloat:
379  return "Column<Array<float>>";
380  case ColumnArrayDouble:
381  return "Column<Array<double>>";
382  case ColumnArrayBool:
383  return "Column<Array<bool>>";
385  return "Column<Array<TextEncodingDict>>";
386  case ColumnListArrayInt8:
387  return "ColumnList<Array<i8>>";
389  return "ColumnList<Array<i16>>";
391  return "ColumnList<Array<i32>>";
393  return "ColumnList<Array<i64>>";
395  return "ColumnList<Array<float>>";
397  return "ColumnList<Array<double>>";
398  case ColumnListArrayBool:
399  return "ColumnList<Array<bool>>";
401  return "ColumnList<Array<TextEncodingDict>>";
402  case DayTimeInterval:
403  return "DayTimeInterval";
405  return "YearMonthTimeInterval";
406  case ColumnGeoPoint:
407  return "Column<GeoPoint>";
408  case ColumnGeoLineString:
409  return "Column<GeoLineString>";
410  case ColumnGeoPolygon:
411  return "Column<GeoPolygon>";
412  case ColumnGeoMultiPoint:
413  return "Column<GeoMultiPoint>";
415  return "Column<GeoMultiLineString>";
417  return "Column<GeoMultiPolygon>";
418  case ColumnListGeoPoint:
419  return "ColumnList<GeoPoint>";
421  return "ColumnList<GeoLineString>";
423  return "ColumnList<GeoPolygon>";
425  return "ColumnList<GeoMultiPoint>";
427  return "ColumnList<GeoMultiLineString>";
429  return "ColumnList<GeoMultiPolygon>";
431  return "Array<TextEncodingNone>";
433  return "Column<TextEncodingNone>";
435  return "ColumnList<TextEncodingNone>";
437  return "Column<Array<TextEncodingNone>>";
439  return "ColumnList<Array<TextEncodingNone>>";
440  }
441  HEAVYDBLOGGER.info("Extensionfunction::typeName: unknown type=`" + type + "`");
442  assert false;
443  return null;
444  }
445 
446  private static String dq(final String str) {
447  return "\"" + str + "\"";
448  }
449 
450  private final List<ExtArgumentType> args;
451  private final List<ExtArgumentType> outs; // only used by UDTFs
452  private final List<String> names;
453  private final ExtArgumentType ret; // only used by UDFs
454  private final boolean isRowUdf;
455  private final List<Map<String, String>> annotations; // only used by UDFs atm
456  private final Map<String, String> options;
457  private final Map<String, List<ExtArgumentType>>
458  cursor_field_types; // only used by UDTFs
459  private final Map<String, Comparable<?>> default_values;
460 
461  public final java.util.List<SqlTypeFamily> toSqlSignature() {
462  java.util.List<SqlTypeFamily> sql_sig = new java.util.ArrayList<SqlTypeFamily>();
463  boolean isRowUdf = this.isRowUdf();
464  for (int arg_idx = 0; arg_idx < this.getArgs().size(); ++arg_idx) {
465  final ExtArgumentType arg_type = this.getArgs().get(arg_idx);
466  if (isRowUdf) {
467  sql_sig.add(toSqlTypeName(arg_type).getFamily());
468  if (isPointerType(arg_type)) {
469  ++arg_idx;
470  }
471  } else {
472  sql_sig.add(toSqlTypeName(arg_type).getFamily());
473  }
474  }
475  return sql_sig;
476  }
477 
478  public static boolean isPointerType(final ExtArgumentType type) {
479  return type == ExtArgumentType.PInt8 || type == ExtArgumentType.PInt16
480  || type == ExtArgumentType.PInt32 || type == ExtArgumentType.PInt64
481  || type == ExtArgumentType.PFloat || type == ExtArgumentType.PDouble
482  || type == ExtArgumentType.PBool;
483  }
484 
485  public static boolean isColumnArrayType(final ExtArgumentType type) {
486  return type == ExtArgumentType.ColumnArrayInt8
487  || type == ExtArgumentType.ColumnArrayInt16
488  || type == ExtArgumentType.ColumnArrayInt32
489  || type == ExtArgumentType.ColumnArrayInt64
490  || type == ExtArgumentType.ColumnArrayFloat
491  || type == ExtArgumentType.ColumnArrayDouble
492  || type == ExtArgumentType.ColumnArrayBool
493  || type == ExtArgumentType.ColumnArrayTextEncodingDict
495  }
496 
497  public static boolean isArrayType(final ExtArgumentType type) {
498  return type == ExtArgumentType.ArrayInt8 || type == ExtArgumentType.ArrayInt16
499  || type == ExtArgumentType.ArrayInt32 || type == ExtArgumentType.ArrayInt64
500  || type == ExtArgumentType.ArrayFloat || type == ExtArgumentType.ArrayDouble
501  || type == ExtArgumentType.ArrayBool
502  || type == ExtArgumentType.ArrayTextEncodingDict
504  }
505 
506  public static boolean isColumnListArrayType(final ExtArgumentType type) {
507  return type == ExtArgumentType.ColumnListArrayInt8
508  || type == ExtArgumentType.ColumnListArrayInt16
509  || type == ExtArgumentType.ColumnListArrayInt32
510  || type == ExtArgumentType.ColumnListArrayInt64
511  || type == ExtArgumentType.ColumnListArrayFloat
512  || type == ExtArgumentType.ColumnListArrayDouble
513  || type == ExtArgumentType.ColumnListArrayBool
514  || type == ExtArgumentType.ColumnListArrayTextEncodingDict
516  }
517 
518  public static boolean isColumnType(final ExtArgumentType type) {
519  return type == ExtArgumentType.ColumnInt8 || type == ExtArgumentType.ColumnInt16
520  || type == ExtArgumentType.ColumnInt32 || type == ExtArgumentType.ColumnInt64
521  || type == ExtArgumentType.ColumnFloat || type == ExtArgumentType.ColumnDouble
522  || type == ExtArgumentType.ColumnBool
523  || type == ExtArgumentType.ColumnTextEncodingDict
524  || type == ExtArgumentType.ColumnTextEncodingNone
525  || type == ExtArgumentType.ColumnTimestamp || isColumnArrayType(type)
526  || type == ExtArgumentType.ColumnGeoPoint
527  || type == ExtArgumentType.ColumnGeoLineString
528  || type == ExtArgumentType.ColumnGeoPolygon
529  || type == ExtArgumentType.ColumnGeoMultiPoint
530  || type == ExtArgumentType.ColumnGeoMultiLineString
532  }
533 
534  public static boolean isColumnListType(final ExtArgumentType type) {
535  return type == ExtArgumentType.ColumnListInt8
536  || type == ExtArgumentType.ColumnListInt16
537  || type == ExtArgumentType.ColumnListInt32
538  || type == ExtArgumentType.ColumnListInt64
539  || type == ExtArgumentType.ColumnListFloat
540  || type == ExtArgumentType.ColumnListDouble
541  || type == ExtArgumentType.ColumnListBool
542  || type == ExtArgumentType.ColumnListTextEncodingDict
543  || type == ExtArgumentType.ColumnListTextEncodingNone
544  || isColumnListArrayType(type) || type == ExtArgumentType.ColumnListGeoPoint
545  || type == ExtArgumentType.ColumnListGeoLineString
546  || type == ExtArgumentType.ColumnListGeoPolygon
547  || type == ExtArgumentType.ColumnListGeoMultiPoint
548  || type == ExtArgumentType.ColumnListGeoMultiLineString
550  }
551 
553  switch (type) {
554  case PInt8:
555  case ArrayInt8:
556  case ColumnInt8:
557  case ColumnListInt8:
558  case Int8:
559  return ExtArgumentType.Int8;
560  case ArrayInt16:
561  case PInt16:
562  case ColumnInt16:
563  case ColumnListInt16:
564  case Int16:
565  return ExtArgumentType.Int16;
566  case ArrayInt32:
567  case PInt32:
568  case ColumnInt32:
569  case ColumnListInt32:
570  case Int32:
571  return ExtArgumentType.Int32;
572  case ArrayInt64:
573  case PInt64:
574  case ColumnInt64:
575  case ColumnListInt64:
576  case Int64:
577  return ExtArgumentType.Int64;
578  case ArrayFloat:
579  case PFloat:
580  case ColumnFloat:
581  case ColumnListFloat:
582  case Float:
583  return ExtArgumentType.Float;
584  case ArrayDouble:
585  case PDouble:
586  case ColumnDouble:
587  case ColumnListDouble:
588  case Double:
589  return ExtArgumentType.Double;
590  case ArrayBool:
591  case PBool:
592  case ColumnBool:
593  case ColumnListBool:
594  case Bool:
595  return ExtArgumentType.Bool;
596  case TextEncodingDict:
604  case ColumnTimestamp:
606  case ColumnArrayInt8:
607  case ColumnListArrayInt8:
609  case ColumnArrayInt16:
612  case ColumnArrayInt32:
615  case ColumnArrayInt64:
618  case ColumnArrayFloat:
621  case ColumnArrayDouble:
624  case ColumnArrayBool:
625  case ColumnListArrayBool:
627  case ColumnGeoPoint:
628  case ColumnListGeoPoint:
630  case ColumnGeoLineString:
633  case ColumnGeoPolygon:
636  case ColumnGeoMultiPoint:
652  }
653  HEAVYDBLOGGER.error("getValueType: no value for type " + type);
654  assert false;
655  return null;
656  }
657 
658  public static ExtArgumentType toSqlTypeName(final String type) {
659  return ExtArgumentType.valueOf(type);
660  }
661 
662  public static RelDataType toRelDataType(
663  final ExtArgumentType type, RelDataTypeFactory factory) {
664  switch (type) {
665  case ArrayInt8:
666  case ArrayInt16:
667  case ArrayInt32:
668  case ArrayInt64:
669  case ArrayFloat:
670  case ArrayDouble:
671  case ArrayBool:
674  return factory.createTypeWithNullability(
675  factory.createArrayType(toRelDataType(getValueType(type), factory), -1),
676  true);
677  case ColumnArrayInt8:
678  case ColumnArrayInt16:
679  case ColumnArrayInt32:
680  case ColumnArrayInt64:
681  case ColumnArrayFloat:
682  case ColumnArrayDouble:
683  case ColumnArrayBool:
686  return factory.createTypeWithNullability(
687  factory.createArrayType(
688  toRelDataType(getValueType(getValueType(type)), factory), -1),
689  true);
690  case Timestamp:
691  return factory.createTypeWithNullability(
692  factory.createSqlType(toSqlTypeName(type), 9), true);
693  case ColumnTimestamp:
694  return factory.createTypeWithNullability(
695  toRelDataType(getValueType(type), factory), true);
697  SqlIntervalQualifier yearMonthIntervalQualifier =
698  new SqlIntervalQualifier(TimeUnit.MONTH, null, SqlParserPos.ZERO);
699  return factory.createSqlIntervalType(yearMonthIntervalQualifier);
700  case DayTimeInterval:
701  SqlIntervalQualifier dayTimeIntervalQualifier =
702  new SqlIntervalQualifier(TimeUnit.DAY, null, SqlParserPos.ZERO);
703  return factory.createSqlIntervalType(dayTimeIntervalQualifier);
704  default:
705  return factory.createTypeWithNullability(
706  factory.createSqlType(toSqlTypeName(type)), true);
707  }
708  }
709 
710  public static SqlTypeName toSqlTypeName(final ExtArgumentType type) {
711  switch (type) {
712  // Column types are mapped to their underlying type for CURSOR typechecking
713  case Bool:
714  case ColumnBool:
715  return SqlTypeName.BOOLEAN;
716  case ColumnInt8:
717  case Int8:
718  return SqlTypeName.TINYINT;
719  case ColumnInt16:
720  case Int16:
721  return SqlTypeName.SMALLINT;
722  case Int32:
723  case ColumnInt32:
724  return SqlTypeName.INTEGER;
725  case Int64:
726  case ColumnInt64:
727  return SqlTypeName.BIGINT;
728  case Float:
729  case ColumnFloat:
730  return SqlTypeName.FLOAT;
731  case Double:
732  case ColumnDouble:
733  return SqlTypeName.DOUBLE;
734  case PInt8:
735  case PInt16:
736  case PInt32:
737  case PInt64:
738  case PFloat:
739  case PDouble:
740  case PBool:
741  case ArrayInt8:
742  case ArrayInt16:
743  case ArrayInt32:
744  case ArrayInt64:
745  case ArrayFloat:
746  case ArrayDouble:
747  case ArrayBool:
750  return SqlTypeName.ARRAY;
751  case ColumnArrayInt8:
752  case ColumnArrayInt16:
753  case ColumnArrayInt32:
754  case ColumnArrayInt64:
755  case ColumnArrayFloat:
756  case ColumnArrayDouble:
757  case ColumnArrayBool:
760  return SqlTypeName.ARRAY;
761  case GeoPoint:
762  case GeoMultiPoint:
763  case GeoLineString:
764  case GeoMultiLineString:
765  case GeoPolygon:
766  case GeoMultiPolygon:
767  case ColumnGeoPoint:
768  case ColumnGeoLineString:
769  case ColumnGeoPolygon:
770  case ColumnGeoMultiPoint:
773  return SqlTypeName.GEOMETRY;
774  case Cursor:
775  return SqlTypeName.CURSOR;
776  case TextEncodingNone:
777  case TextEncodingDict:
780  return SqlTypeName.VARCHAR;
781  case Timestamp:
782  case ColumnTimestamp:
783  return SqlTypeName.TIMESTAMP;
784  case ColumnListInt8:
785  case ColumnListInt16:
786  case ColumnListInt32:
787  case ColumnListInt64:
788  case ColumnListFloat:
789  case ColumnListDouble:
790  case ColumnListBool:
791  case ColumnListArrayInt8:
797  case ColumnListArrayBool:
800  case ColumnListGeoPoint:
808  return SqlTypeName.COLUMN_LIST;
809  case DayTimeInterval:
810  return SqlTypeName.INTERVAL_DAY_HOUR;
812  return SqlTypeName.INTERVAL_YEAR_MONTH;
813  case Void:
814  // some extension functions return void. these functions should be defined in
815  // HeavyDBSqlOperatorTable and never have their definition set from the AST file
816  return null;
817  }
818  Set<SqlTypeName> allSqlTypeNames = EnumSet.allOf(SqlTypeName.class);
819  HEAVYDBLOGGER.error("toSqlTypeName: unknown type " + type + " to be mapped to {"
820  + allSqlTypeNames + "}");
821  assert false;
822  return null;
823  }
824 }
static RelDataType toRelDataType(final ExtArgumentType type, RelDataTypeFactory factory)
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:158
ExtensionFunction(final List< ExtArgumentType > args, final List< ExtArgumentType > outs, final List< String > names, final Map< String, String > options, final Map< String, List< ExtArgumentType >> cursor_field_types, final Map< String, java.lang.Comparable<?>> default_values)
static SqlTypeName toSqlTypeName(final ExtArgumentType type)
Map< String, List< ExtArgumentType > > getCursorFieldTypes()
Simplified core of GeoJSON Polygon coordinates definition.
final Map< String, Comparable<?> > default_values
Map< String, Comparable<?> > getDefaultValues()
static boolean isColumnListArrayType(final ExtArgumentType type)
std::vector< std::string > split(std::string_view str, std::string_view delim, std::optional< size_t > maxsplit)
split apart a string into a vector of substrings
Simplified core of GeoJSON MultiPolygon coordinates definition.
static boolean isColumnListType(final ExtArgumentType type)
static boolean isColumnType(final ExtArgumentType type)
static boolean isColumnArrayType(final ExtArgumentType type)
ExtensionFunction(final List< ExtArgumentType > args, final ExtArgumentType ret, final List< Map< String, String >> annotations)
static String typeName(final ExtArgumentType type)
final List< Map< String, String > > annotations
static boolean isArrayType(final ExtArgumentType type)
static ExtArgumentType toSqlTypeName(final String type)
static String dq(final String str)
string name
Definition: setup.in.py:72
final Map< String, List< ExtArgumentType > > cursor_field_types
static boolean isPointerType(final ExtArgumentType type)
static ExtArgumentType getValueType(final ExtArgumentType type)