OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HeavyDBSqlOperatorTable.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.calcite.parser;
18 
20 
21 import static org.apache.calcite.util.Static.RESOURCE;
22 
23 import com.google.common.base.Predicate;
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.collect.Multimap;
31 
32 import org.apache.calcite.linq4j.Ord;
33 import org.apache.calcite.rel.metadata.RelColumnMapping;
34 import org.apache.calcite.rel.type.RelDataType;
35 import org.apache.calcite.rel.type.RelDataTypeFactory;
36 import org.apache.calcite.rel.type.RelDataTypeFactory.FieldInfoBuilder;
37 import org.apache.calcite.rel.type.RelDataTypeFamily;
38 import org.apache.calcite.runtime.Resources;
39 import org.apache.calcite.runtime.Resources.BaseMessage;
40 import org.apache.calcite.runtime.Resources.ExInst;
41 import org.apache.calcite.schema.FunctionParameter;
42 import org.apache.calcite.sql.SqlAggFunction;
43 import org.apache.calcite.sql.SqlBasicCall;
44 import org.apache.calcite.sql.SqlCall;
45 import org.apache.calcite.sql.SqlCallBinding;
46 import org.apache.calcite.sql.SqlDynamicParam;
47 import org.apache.calcite.sql.SqlFunction;
48 import org.apache.calcite.sql.SqlFunctionCategory;
49 import org.apache.calcite.sql.SqlIdentifier;
50 import org.apache.calcite.sql.SqlIntervalQualifier;
51 import org.apache.calcite.sql.SqlKind;
52 import org.apache.calcite.sql.SqlLiteral;
53 import org.apache.calcite.sql.SqlNode;
54 import org.apache.calcite.sql.SqlOperandCountRange;
56 import org.apache.calcite.sql.SqlOperatorBinding;
57 import org.apache.calcite.sql.SqlOperatorTable;
58 import org.apache.calcite.sql.SqlSyntax;
59 import org.apache.calcite.sql.SqlTableFunction;
60 import org.apache.calcite.sql.SqlUtil;
61 import org.apache.calcite.sql.SqlWriter;
62 import org.apache.calcite.sql.fun.SqlArrayValueConstructor;
63 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
64 import org.apache.calcite.sql.parser.SqlParserPos;
65 import org.apache.calcite.sql.type.InferTypes;
66 import org.apache.calcite.sql.type.OperandTypes;
67 import org.apache.calcite.sql.type.ReturnTypes;
68 import org.apache.calcite.sql.type.SameOperandTypeChecker;
69 import org.apache.calcite.sql.type.SqlOperandCountRanges;
70 import org.apache.calcite.sql.type.SqlReturnTypeInference;
71 import org.apache.calcite.sql.type.SqlTypeFamily;
72 import org.apache.calcite.sql.type.SqlTypeName;
73 import org.apache.calcite.sql.type.SqlTypeTransforms;
74 import org.apache.calcite.sql.type.SqlTypeUtil;
75 import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
76 import org.apache.calcite.sql.util.ListSqlOperatorTable;
77 import org.apache.calcite.sql.util.ReflectiveSqlOperatorTable;
78 import org.apache.calcite.sql.validate.SqlNameMatcher;
79 import org.apache.calcite.sql.validate.SqlValidator;
80 import org.apache.calcite.sql.validate.SqlValidatorException;
82 import org.apache.calcite.sql.validate.SqlValidatorScope;
83 import org.apache.calcite.util.Optionality;
84 import org.checkerframework.checker.nullness.qual.Nullable;
85 import org.slf4j.Logger;
86 import org.slf4j.LoggerFactory;
87 
88 import java.lang.reflect.Field;
89 import java.util.Arrays;
90 import java.util.EnumSet;
91 import java.util.HashSet;
92 import java.util.Iterator;
93 import java.util.List;
94 import java.util.Locale;
95 import java.util.Map;
96 import java.util.Set;
97 import java.util.stream.Collectors;
98 
99 class CaseInsensitiveListSqlOperatorTable extends ListSqlOperatorTable {
100  @Override
101  public void lookupOperatorOverloads(SqlIdentifier opName,
102  SqlFunctionCategory category,
103  SqlSyntax syntax,
104  List<SqlOperator> operatorList,
105  SqlNameMatcher nameMatcher) {
106  for (SqlOperator operator : this.getOperatorList()) {
107  if (operator.getSyntax() != syntax) {
108  continue;
109  }
110  if (!opName.isSimple()
111  || !nameMatcher.matches(operator.getName(), opName.getSimple())) {
112  continue;
113  }
114  SqlFunctionCategory functionCategory;
115  if (operator instanceof SqlFunction) {
116  functionCategory = ((SqlFunction) operator).getFunctionType();
117  } else {
118  functionCategory = SqlFunctionCategory.SYSTEM;
119  }
120  if (category != functionCategory
121  && category != SqlFunctionCategory.USER_DEFINED_FUNCTION) {
122  continue;
123  }
124  operatorList.add(operator);
125  }
126  }
127 }
128 
129 public class HeavyDBSqlOperatorTable extends ChainedSqlOperatorTable {
132  public static final SqlFunction TRY_CAST = new TryCast();
133 
134  static {
135  try {
136  // some nasty bit to remove the std APPROX_COUNT_DISTINCT function definition
137  {
138  Field f = ReflectiveSqlOperatorTable.class.getDeclaredField(
139  "caseSensitiveOperators");
140  f.setAccessible(true);
141  Multimap operators = (Multimap) f.get(SqlStdOperatorTable.instance());
142  for (Iterator i = operators.entries().iterator(); i.hasNext();) {
143  Map.Entry entry = (Map.Entry) i.next();
144  if (entry.getValue() == SqlStdOperatorTable.APPROX_COUNT_DISTINCT
145  || entry.getValue() == SqlStdOperatorTable.AVG
146  || entry.getValue() == SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR) {
147  i.remove();
148  }
149  }
150  }
151 
152  {
153  Field f = ReflectiveSqlOperatorTable.class.getDeclaredField(
154  "caseInsensitiveOperators");
155  f.setAccessible(true);
156  Multimap operators = (Multimap) f.get(SqlStdOperatorTable.instance());
157  for (Iterator i = operators.entries().iterator(); i.hasNext();) {
158  Map.Entry entry = (Map.Entry) i.next();
159  if (entry.getValue() == SqlStdOperatorTable.APPROX_COUNT_DISTINCT
160  || entry.getValue() == SqlStdOperatorTable.AVG
161  || entry.getValue() == SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR) {
162  i.remove();
163  }
164  }
165  }
166 
167  SqlStdOperatorTable.instance().register(ARRAY_VALUE_CONSTRUCTOR);
168 
169  } catch (Exception e) {
170  throw new RuntimeException(e);
171  }
172 
173  // register our approx count distinct against std table
174  // SqlStdOperatorTable.instance().register(new ApproxCountDistinct());
175  }
176 
177  final static Logger HEAVYDBLOGGER =
178  LoggerFactory.getLogger(HeavyDBSqlOperatorTable.class);
179 
184  // ~ Instance fields --------------------------------------------------------
185  private final ListSqlOperatorTable listOpTab;
186 
187  // ~ Constructors -----------------------------------------------------------
188  public HeavyDBSqlOperatorTable(SqlOperatorTable parentTable) {
189  super(ImmutableList.of(parentTable, new CaseInsensitiveListSqlOperatorTable()));
190  listOpTab = (ListSqlOperatorTable) tableList.get(1);
191  }
192 
198  public void addOperator(SqlOperator op) {
199  listOpTab.add(op);
200  }
201 
202  public void addUDF(final Map<String, ExtensionFunction> extSigs) {
203  // Don't use anonymous inner classes. They can't be instantiated
204  // using reflection when we are deserializing from JSON.
205  addOperator(new MyUDFFunction());
206  addOperator(new PgUnnest());
207  addOperator(new Any());
208  addOperator(new All());
209  addOperator(new Now());
210  addOperator(new Datetime());
211  addOperator(new PgExtract());
212  addOperator(new Dateadd());
213  addOperator(new Datediff());
214  addOperator(new Datepart());
215  addOperator(new PgDateTrunc());
216  addOperator(new Length());
217  addOperator(new CharLength());
218  addOperator(new KeyForString());
219  addOperator(new SampleRatio());
220  addOperator(new WidthBucket());
221  addOperator(new ArrayLength());
222  addOperator(new PgILike());
223  addOperator(new LTrim());
224  addOperator(new RTrim());
225  addOperator(new LPad());
226  addOperator(new RPad());
227  addOperator(new Replace());
228  addOperator(new Reverse());
229  addOperator(new Repeat());
230  addOperator(new SplitPart());
231  addOperator(new RegexpLike());
232  addOperator(new RegexpReplace());
233  addOperator(new RegexpSubstr());
234  addOperator(new RegexpMatch());
235  addOperator(new RegexpCount());
236  addOperator(new Base64Encode());
237  addOperator(new Base64Decode());
238  addOperator(new UrlEncode());
239  addOperator(new UrlDecode());
242  addOperator(new Hash());
243  addOperator(new Likely());
244  addOperator(new Unlikely());
245  addOperator(new Sign());
246  addOperator(new Truncate());
247  addOperator(new TryCast());
248  addOperator(new ST_IsEmpty());
249  addOperator(new ST_IsValid());
250  addOperator(new ST_Contains());
251  addOperator(new ST_Equals());
252  addOperator(new ST_Intersects());
255  addOperator(new ST_Disjoint());
256  addOperator(new ST_Within());
257  addOperator(new ST_DWithin());
259  addOperator(new ST_Distance());
263  addOperator(new ST_Transform());
264  addOperator(new ST_X());
265  addOperator(new ST_Y());
266  addOperator(new ST_XMin());
267  addOperator(new ST_XMax());
268  addOperator(new ST_YMin());
269  addOperator(new ST_YMax());
270  addOperator(new ST_PointN());
271  addOperator(new ST_StartPoint());
272  addOperator(new ST_EndPoint());
273  addOperator(new ST_Length());
274  addOperator(new ST_Perimeter());
275  addOperator(new ST_Area());
276  addOperator(new ST_NPoints());
277  addOperator(new ST_NRings());
279  addOperator(new ST_SRID());
280  addOperator(new ST_SetSRID());
281  addOperator(new ST_Point());
282  addOperator(new ST_Centroid());
283  addOperator(new ST_Buffer());
285  addOperator(new ST_ConvexHull());
287  addOperator(new ST_Union());
288  addOperator(new ST_Difference());
290  addOperator(new EncodeText());
293  addOperator(new ApproxMedian());
296  addOperator(new MapDAvg());
297  addOperator(new Mode());
298  addOperator(new Sample());
299  addOperator(new LastSample());
300  addOperator(new ForwardFill());
301  addOperator(new BackwardFill());
302 
303  // window functions on window frame
307  addOperator(new LagInFrame());
308  addOperator(new LeadInFrame());
309 
310  // conditional window aggregate functions
311  addOperator(new CountIf());
312  addOperator(new SumIf());
314 
320  addOperator(new usTimestamp());
321  addOperator(new nsTimestamp());
322 
323  addOperator(new MLPredict());
324  addOperator(new PCAProject());
325 
326  if (extSigs == null) {
327  return;
328  }
329  HashSet<String> demangledNames = new HashSet<String>();
330  for (Map.Entry<String, ExtensionFunction> extSig : extSigs.entrySet()) {
331  final String demangledName = dropSuffix(extSig.getKey());
332  final String demangledNameArity = extSig.getValue().isTableUdf()
333  ? String.format("%s-%s-%s",
334  demangledName,
335  extSig.getValue().getArgs(),
336  extSig.getValue().getCursorFieldTypes())
337  : String.format("%s-%d", demangledName, extSig.getValue().getArgs().size());
338  if (demangledNames.contains(demangledNameArity)) {
339  continue;
340  }
341  demangledNames.add(demangledNameArity);
342  if (extSig.getValue().isRowUdf()) {
343  addOperator(new ExtFunction(demangledName, extSig.getValue()));
344  } else {
345  addOperator(new ExtTableFunction(demangledName, extSig.getValue()));
346  }
347  }
348  }
349 
350  private static String dropSuffix(final String str) {
351  int suffix_idx = str.indexOf("__");
352  if (suffix_idx == -1) {
353  return str;
354  }
355  assert suffix_idx > 0;
356  return str.substring(0, suffix_idx);
357  }
358 
359  //@Deprecated // to be removed before 2.0
360  // public static final SqlFunction LTRIM = SqlLibraryOperators.LTRIM;
361 
362  //@Deprecated // to be removed before 2.0
363  // public static final SqlFunction RTRIM = SqlLibraryOperators.RTRIM;
364 
366  extends SqlArrayValueConstructor {
367  @Override
368  protected RelDataType getComponentType(
369  RelDataTypeFactory typeFactory, List<RelDataType> argTypes) {
370  if (argTypes.isEmpty()) {
371  return typeFactory.createSqlType(SqlTypeName.NULL);
372  }
373  return super.getComponentType(typeFactory, argTypes);
374  }
375 
376  @Override
377  public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
378  if (callBinding.operands().isEmpty()) {
379  return true;
380  }
381  return super.checkOperandTypes(callBinding, throwOnFailure);
382  }
383  }
384 
388  public static class RampFunction extends SqlFunction {
389  public RampFunction() {
390  super("RAMP",
391  SqlKind.OTHER_FUNCTION,
392  null,
393  null,
394  OperandTypes.NUMERIC,
395  SqlFunctionCategory.USER_DEFINED_FUNCTION);
396  }
397 
398  @Override
399  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
400  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
401  return typeFactory.builder().add("I", SqlTypeName.INTEGER).build();
402  }
403  }
404 
408  public static class DedupFunction extends SqlFunction {
409  public DedupFunction() {
410  super("DEDUP",
411  SqlKind.OTHER_FUNCTION,
412  null,
413  null,
414  OperandTypes.VARIADIC,
415  SqlFunctionCategory.USER_DEFINED_FUNCTION);
416  }
417 
418  @Override
419  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
420  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
421  return typeFactory.builder().add("NAME", SqlTypeName.VARCHAR, 1024).build();
422  }
423  }
424 
429  public static class MyUDFFunction extends SqlFunction {
430  public MyUDFFunction() {
431  super("MyUDF",
432  SqlKind.OTHER_FUNCTION,
433  null,
434  null,
435  OperandTypes.STRING_STRING,
436  SqlFunctionCategory.SYSTEM);
437  }
438 
439  @Override
440  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
441  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
442  return typeFactory.createSqlType(SqlTypeName.BIGINT);
443  }
444  }
445 
446  /* Postgres-style UNNEST */
447  public static class PgUnnest extends SqlFunction {
448  public PgUnnest() {
449  super("PG_UNNEST",
450  SqlKind.OTHER_FUNCTION,
451  null,
452  null,
453  OperandTypes.ARRAY,
454  SqlFunctionCategory.SYSTEM);
455  }
456 
457  @Override
458  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
459  assert opBinding.getOperandCount() == 1;
460  RelDataType elem_type = opBinding.getOperandType(0).getComponentType();
461  assert elem_type != null;
462  return elem_type;
463  }
464  }
465 
466  /* ANY qualifier */
467  public static class Any extends SqlFunction {
468  public Any() {
469  super("PG_ANY",
470  SqlKind.OTHER_FUNCTION,
471  null,
472  null,
473  OperandTypes.ARRAY,
474  SqlFunctionCategory.SYSTEM);
475  }
476 
477  @Override
478  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
479  assert opBinding.getOperandCount() == 1;
480  RelDataType elem_type = opBinding.getOperandType(0).getComponentType();
481  assert elem_type != null;
482  return elem_type;
483  }
484  }
485 
486  /* ALL qualifier */
487  public static class All extends SqlFunction {
488  public All() {
489  super("PG_ALL",
490  SqlKind.OTHER_FUNCTION,
491  null,
492  null,
493  OperandTypes.ARRAY,
494  SqlFunctionCategory.SYSTEM);
495  }
496 
497  @Override
498  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
499  assert opBinding.getOperandCount() == 1;
500  RelDataType elem_type = opBinding.getOperandType(0).getComponentType();
501  assert elem_type != null;
502  return elem_type;
503  }
504  }
505 
506  /* NOW() */
507  public static class Now extends SqlFunction {
508  public Now() {
509  super("NOW",
510  SqlKind.OTHER_FUNCTION,
511  null,
512  null,
513  OperandTypes.NILADIC,
514  SqlFunctionCategory.SYSTEM);
515  }
516 
517  @Override
518  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
519  assert opBinding.getOperandCount() == 0;
520  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
521  return typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
522  }
523  }
524 
525  /* DATETIME */
526  public static class Datetime extends SqlFunction {
527  public Datetime() {
528  super("DATETIME",
529  SqlKind.OTHER_FUNCTION,
530  null,
531  null,
532  OperandTypes.STRING,
533  SqlFunctionCategory.SYSTEM);
534  }
535 
536  @Override
537  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
538  assert opBinding.getOperandCount() == 1;
539  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
540  return typeFactory.createSqlType(
541  SqlTypeName.TIMESTAMP, opBinding.getOperandType(0).getPrecision());
542  }
543  }
544 
545  /* Postgres-style EXTRACT */
546  public static class PgExtract extends SqlFunction {
547  public PgExtract() {
548  super("PG_EXTRACT",
549  SqlKind.OTHER_FUNCTION,
550  null,
551  null,
552  OperandTypes.family(SqlTypeFamily.STRING, SqlTypeFamily.DATETIME),
553  SqlFunctionCategory.SYSTEM);
554  }
555 
556  @Override
557  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
558  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
559  return typeFactory.createTypeWithNullability(
560  typeFactory.createSqlType(SqlTypeName.BIGINT),
561  opBinding.getOperandType(1).isNullable());
562  }
563  }
564 
565  public static class Datepart extends SqlFunction {
566  public Datepart() {
567  super("DATEPART",
568  SqlKind.OTHER_FUNCTION,
569  null,
570  null,
571  OperandTypes.family(SqlTypeFamily.STRING, SqlTypeFamily.DATETIME),
572  SqlFunctionCategory.TIMEDATE);
573  }
574 
575  @Override
576  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
577  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
578  return typeFactory.createTypeWithNullability(
579  typeFactory.createSqlType(SqlTypeName.BIGINT),
580  opBinding.getOperandType(1).isNullable());
581  }
582  }
583 
584  public static class Dateadd extends SqlFunction {
585  public Dateadd() {
586  super("DATEADD",
587  SqlKind.OTHER_FUNCTION,
588  null,
589  null,
590  OperandTypes.family(SqlTypeFamily.STRING,
591  SqlTypeFamily.INTEGER,
592  SqlTypeFamily.DATETIME),
593  SqlFunctionCategory.TIMEDATE);
594  }
595 
596  @Override
597  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
598  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
599  return typeFactory.createTypeWithNullability(
600  typeFactory.createSqlType(
601  SqlTypeName.TIMESTAMP, opBinding.getOperandType(2).getPrecision()),
602  opBinding.getOperandType(2).isNullable());
603  }
604  }
605 
606  public static class Datediff extends SqlFunction {
607  public Datediff() {
608  super("DATEDIFF",
609  SqlKind.OTHER_FUNCTION,
610  null,
611  null,
612  OperandTypes.family(SqlTypeFamily.STRING,
613  SqlTypeFamily.DATETIME,
614  SqlTypeFamily.DATETIME),
615  SqlFunctionCategory.TIMEDATE);
616  }
617 
618  @Override
619  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
620  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
621  return typeFactory.createTypeWithNullability(
622  typeFactory.createSqlType(SqlTypeName.BIGINT),
623  opBinding.getOperandType(1).isNullable()
624  || opBinding.getOperandType(2).isNullable());
625  }
626  }
627 
628  /* Postgres-style DATE_TRUNC */
629  public static class PgDateTrunc extends SqlFunction {
630  public PgDateTrunc() {
631  super("PG_DATE_TRUNC",
632  SqlKind.OTHER_FUNCTION,
633  null,
634  null,
635  OperandTypes.family(SqlTypeFamily.STRING, SqlTypeFamily.DATETIME),
636  SqlFunctionCategory.SYSTEM);
637  }
638 
639  @Override
640  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
641  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
642  return typeFactory.createTypeWithNullability(
643  typeFactory.createSqlType(
644  SqlTypeName.TIMESTAMP, opBinding.getOperandType(1).getPrecision()),
645  opBinding.getOperandType(1).isNullable());
646  }
647  }
648 
649  public static class Length extends SqlFunction {
650  public Length() {
651  super("LENGTH",
652  SqlKind.OTHER_FUNCTION,
653  null,
654  null,
655  OperandTypes.STRING,
656  SqlFunctionCategory.SYSTEM);
657  }
658 
659  @Override
660  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
661  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
662  return typeFactory.createSqlType(SqlTypeName.INTEGER);
663  }
664  }
665 
666  public static class CharLength extends SqlFunction {
667  public CharLength() {
668  super("CHAR_LENGTH",
669  SqlKind.OTHER_FUNCTION,
670  null,
671  null,
672  OperandTypes.STRING,
673  SqlFunctionCategory.SYSTEM);
674  }
675 
676  @Override
677  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
678  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
679  return typeFactory.createSqlType(SqlTypeName.INTEGER);
680  }
681  }
682 
683  public static class KeyForString extends SqlFunction {
684  public KeyForString() {
685  super("KEY_FOR_STRING",
686  SqlKind.OTHER_FUNCTION,
687  null,
688  null,
689  OperandTypes.STRING,
690  SqlFunctionCategory.SYSTEM);
691  }
692 
693  @Override
694  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
695  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
696  return typeFactory.createTypeWithNullability(
697  typeFactory.createSqlType(SqlTypeName.INTEGER),
698  opBinding.getOperandType(0).isNullable());
699  }
700  }
701 
702  public static class SampleRatio extends SqlFunction {
703  public SampleRatio() {
704  super("SAMPLE_RATIO",
705  SqlKind.OTHER_FUNCTION,
706  null,
707  null,
708  OperandTypes.family(signature()),
709  SqlFunctionCategory.SYSTEM);
710  }
711 
712  @Override
713  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
714  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
715  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
716  }
717 
718  private static java.util.List<SqlTypeFamily> signature() {
719  java.util.ArrayList<SqlTypeFamily> families =
720  new java.util.ArrayList<SqlTypeFamily>();
721  families.add(SqlTypeFamily.NUMERIC);
722  return families;
723  }
724  }
725 
726  public static class WidthBucket extends SqlFunction {
727  public WidthBucket() {
728  super("WIDTH_BUCKET",
729  SqlKind.OTHER_FUNCTION,
730  null,
731  null,
732  OperandTypes.family(signature()),
733  SqlFunctionCategory.SYSTEM);
734  }
735 
736  @Override
737  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
738  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
739  return typeFactory.createTypeWithNullability(
740  typeFactory.createSqlType(SqlTypeName.INTEGER), /*nullable=*/true);
741  }
742 
743  private static java.util.List<SqlTypeFamily> signature() {
744  java.util.ArrayList<SqlTypeFamily> families =
745  new java.util.ArrayList<SqlTypeFamily>();
746  families.add(SqlTypeFamily.NUMERIC);
747  families.add(SqlTypeFamily.NUMERIC);
748  families.add(SqlTypeFamily.NUMERIC);
749  families.add(SqlTypeFamily.INTEGER);
750  return families;
751  }
752  }
753 
754  public static class MLPredict extends SqlFunction {
755  public MLPredict() {
756  super("ML_PREDICT",
757  SqlKind.OTHER_FUNCTION,
758  null,
759  null,
760  null,
761  SqlFunctionCategory.SYSTEM);
762  }
763 
764  @Override
765  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
766  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
767  return typeFactory.createTypeWithNullability(
768  typeFactory.createSqlType(SqlTypeName.DOUBLE), /*nullable=*/true);
769  }
770 
771  @Override
772  public SqlOperandCountRange getOperandCountRange() {
773  return SqlOperandCountRanges.from(2);
774  }
775 
776  @Override
777  public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
778  // A call to ML_PREDICT can take the following arguemnts
779  // 1. A text literal with the model name - REQUIRED
780  // 2. Any number of optional text column arguments
781  // 3. Any number of numeric arguments
782  final SqlValidator validator = callBinding.getValidator();
783 
784  final int num_operands = callBinding.getOperandCount();
785  if (num_operands < 2) {
786  throw new IllegalArgumentException(
787  "At least 2 arguments are required, the model name and one or more predictors.");
788  }
789  for (int operand_idx = 0; operand_idx < num_operands; operand_idx++) {
790  final SqlNode operand = callBinding.operand(operand_idx);
791  final SqlTypeName operand_type =
792  validator.getValidatedNodeType(operand).getSqlTypeName();
793  final SqlTypeFamily operand_type_family = operand_type.getFamily();
794  if (operand_idx == 0) {
795  if (!operand.isA(EnumSet.of(SqlKind.LITERAL))
796  || operand_type_family != SqlTypeFamily.CHARACTER) {
797  throw new IllegalArgumentException(
798  "First argument must be TEXT literal denoting the model name.");
799  }
800  } else {
801  if (operand.isA(EnumSet.of(SqlKind.LITERAL))) {
802  throw new IllegalArgumentException(
803  "Literals are not supported as predictors.");
804  }
805  if (!(operand_type_family == SqlTypeFamily.NUMERIC
806  || operand_type_family == SqlTypeFamily.CHARACTER)) {
807  throw new IllegalArgumentException(
808  "Only TEXT and NUMERIC predictors are supported.");
809  }
810  }
811  }
812  return true;
813  }
814  }
815 
816  public static class PCAProject extends SqlFunction {
817  public PCAProject() {
818  super("PCA_PROJECT",
819  SqlKind.OTHER_FUNCTION,
820  null,
821  null,
822  null,
823  SqlFunctionCategory.SYSTEM);
824  }
825 
826  @Override
827  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
828  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
829  return typeFactory.createTypeWithNullability(
830  typeFactory.createSqlType(SqlTypeName.DOUBLE), /*nullable=*/true);
831  }
832 
833  @Override
834  public SqlOperandCountRange getOperandCountRange() {
835  return SqlOperandCountRanges.from(3);
836  }
837 
838  @Override
839  public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
840  // A call to PCA_PROJECT can take the following arguemnts
841  // 1. A text literal with the model name - REQUIRED
842  // 2. Any number of optional text column arguments
843  // 3. Any number of numeric arguments
844  // 4. A numeric literal with the nth principal component to project to
845  final SqlValidator validator = callBinding.getValidator();
846 
847  final int num_operands = callBinding.getOperandCount();
848  if (num_operands < 3) {
849  throw new IllegalArgumentException(
850  "At least 3 arguments are required, the model name, one or more features, and the nth principal component to project to.");
851  }
852  for (int operand_idx = 0; operand_idx < num_operands; operand_idx++) {
853  final SqlNode operand = callBinding.operand(operand_idx);
854  final SqlTypeName operand_type =
855  validator.getValidatedNodeType(operand).getSqlTypeName();
856  final SqlTypeFamily operand_type_family = operand_type.getFamily();
857  if (operand_idx == 0) {
858  if (!operand.isA(EnumSet.of(SqlKind.LITERAL))
859  || operand_type_family != SqlTypeFamily.CHARACTER) {
860  throw new IllegalArgumentException(
861  "First argument must be TEXT literal denoting the model name.");
862  }
863  } else if (operand_idx < num_operands - 1) {
864  if (operand.isA(EnumSet.of(SqlKind.LITERAL))) {
865  throw new IllegalArgumentException("Literals are not supported as features.");
866  }
867  if (!(operand_type_family == SqlTypeFamily.NUMERIC
868  || operand_type_family == SqlTypeFamily.CHARACTER)) {
869  throw new IllegalArgumentException(
870  "Only TEXT and NUMERIC features are supported.");
871  }
872  } else if (!operand.isA(EnumSet.of(SqlKind.LITERAL))
873  || !(operand_type_family == SqlTypeFamily.NUMERIC)
874  || !(operand_type.equals(SqlTypeName.INTEGER))) {
875  throw new IllegalArgumentException(
876  "Last argument to PCA_PROJECT expects integer literal dimension index.");
877  }
878  }
879  return true;
880  }
881  }
882 
883  public static class LeadInFrame extends SqlLeadLag {
884  public LeadInFrame() {
885  super("LEAD_IN_FRAME", SqlKind.LEAD);
886  }
887  }
888 
889  public static class LagInFrame extends SqlLeadLag {
890  public LagInFrame() {
891  super("LAG_IN_FRAME", SqlKind.LAG);
892  }
893  }
894 
895  public static class NthValueInFrame extends SqlNthValueInFrame {
896  public NthValueInFrame() {
897  super("NTH_VALUE_IN_FRAME");
898  }
899  }
900 
901  public static class FirstValueInFrame extends SqlFirstLastValueInFrame {
902  public FirstValueInFrame() {
903  super("FIRST_VALUE_IN_FRAME", SqlKind.FIRST_VALUE);
904  }
905  }
906 
907  public static class LastValueInFrame extends SqlFirstLastValueInFrame {
908  public LastValueInFrame() {
909  super("LAST_VALUE_IN_FRAME", SqlKind.LAST_VALUE);
910  }
911  }
912 
913  public static class ArrayLength extends SqlFunction {
914  public ArrayLength() {
915  super("ARRAY_LENGTH",
916  SqlKind.OTHER_FUNCTION,
917  null,
918  null,
919  OperandTypes.ARRAY,
920  SqlFunctionCategory.SYSTEM);
921  }
922 
923  @Override
924  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
925  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
926  return typeFactory.createSqlType(SqlTypeName.INTEGER);
927  }
928 
929  @Override
930  public void validateCall(SqlCall call,
931  SqlValidator validator,
932  SqlValidatorScope scope,
933  SqlValidatorScope operandScope) {
934  for (int i = 0; i < call.operandCount(); ++i) {
935  SqlNode operand = call.operand(i);
936  if (operand instanceof SqlCall) {
937  SqlCall operand_call = (SqlCall) operand;
938  SqlOperator call_oper = operand_call.getOperator();
939  if (call_oper instanceof SqlFunction) {
940  SqlFunction call_func = (SqlFunction) call_oper;
941  if (call_func.getFunctionType()
942  == SqlFunctionCategory.USER_DEFINED_FUNCTION) {
943  // Cannot call ARRAY_LENGTH(UDF_func) as its llvm return type
944  // is different than the one expected by ARRAY_LENGTH
945  // - UDF(...) -> {T*, i64, i8}*
946  // - ARRAY_LENGTH(chunk_iter*) -> i32
947  throw validator.newValidationError(
948  call, _ERRORS.illegalArrayLengthCall(call.toString()));
949  }
950  }
951  }
952  }
953  super.validateCall(call, validator, scope, operandScope);
954  }
955 
956  public interface ArrayLengthErrors {
957  @BaseMessage("Illegal argument to 'ARRAY_LENGTH': ''{0}''")
958  ExInst<SqlValidatorException> illegalArrayLengthCall(String query);
959  }
960 
961  public static final ArrayLengthErrors _ERRORS =
962  Resources.create(ArrayLengthErrors.class);
963  }
964 
965  public static class PgILike extends SqlFunction {
966  public PgILike() {
967  super("PG_ILIKE",
968  SqlKind.OTHER_FUNCTION,
969  null,
970  null,
971  OperandTypes.family(getSignatureFamilies(), new EscapeOptional()),
972  SqlFunctionCategory.SYSTEM);
973  }
974 
975  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
976  java.util.ArrayList<SqlTypeFamily> families =
977  new java.util.ArrayList<SqlTypeFamily>();
978  families.add(SqlTypeFamily.STRING);
979  families.add(SqlTypeFamily.STRING);
980  families.add(SqlTypeFamily.STRING);
981  return families;
982  }
983 
984  private static class EscapeOptional
985  implements java.util.function.Predicate<Integer>, Predicate<Integer> {
986  @Override
987  public boolean test(Integer t) {
988  return apply(t);
989  }
990 
991  @Override
992  public boolean apply(Integer t) {
993  return t == 2;
994  }
995  }
996 
997  @Override
998  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
999  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1000  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
1001  }
1002  }
1003 
1004  public static class RegexpLike extends SqlFunction {
1005  public RegexpLike() {
1006  super("REGEXP_LIKE",
1007  SqlKind.OTHER_FUNCTION,
1008  null,
1009  null,
1010  OperandTypes.family(getSignatureFamilies(), new EscapeOptional()),
1011  SqlFunctionCategory.SYSTEM);
1012  }
1013 
1014  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1015  java.util.ArrayList<SqlTypeFamily> families =
1016  new java.util.ArrayList<SqlTypeFamily>();
1017  families.add(SqlTypeFamily.STRING);
1018  families.add(SqlTypeFamily.STRING);
1019  families.add(SqlTypeFamily.STRING);
1020  return families;
1021  }
1022 
1023  private static class EscapeOptional
1024  implements java.util.function.Predicate<Integer>, Predicate<Integer> {
1025  @Override
1026  public boolean test(Integer t) {
1027  return apply(t);
1028  }
1029 
1030  public boolean apply(Integer t) {
1031  return t == 2;
1032  }
1033  }
1034 
1035  @Override
1036  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1037  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1038  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
1039  }
1040  }
1041 
1042  public static class LeftRightTrim extends SqlFunction {
1043  public LeftRightTrim(final String name, final SqlKind kind) {
1044  super(name,
1045  kind,
1046  ReturnTypes.ARG0.andThen(SqlTypeTransforms.TO_NULLABLE)
1047  .andThen(SqlTypeTransforms.TO_VARYING),
1048  null,
1049  OperandTypes.and(
1050  OperandTypes.family(SqlTypeFamily.STRING, SqlTypeFamily.STRING),
1051  new SameOperandTypeChecker(2) {
1052  @Override
1053  protected List<Integer> getOperandList(int operandCount) {
1054  return ImmutableList.of(0, 1);
1055  }
1056  }),
1057  SqlFunctionCategory.STRING);
1058  }
1059 
1060  @Override
1061  public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
1062  SqlParserPos pos,
1063  @Nullable SqlNode... operands) {
1064  assert functionQualifier == null;
1065  switch (operands.length) {
1066  case 1:
1067  operands = new SqlNode[] {operands[0], SqlLiteral.createCharString(" ", pos)};
1068  break;
1069  case 2:
1070  if (operands[1] == null) {
1071  operands[1] = SqlLiteral.createCharString(" ", pos);
1072  }
1073  operands = new SqlNode[] {operands[0], operands[1]};
1074  break;
1075  default:
1076  throw new IllegalArgumentException(
1077  "Invalid operand count " + Arrays.toString(operands));
1078  }
1079  return super.createCall(functionQualifier, pos, operands);
1080  }
1081 
1082  @Override
1083  public boolean requiresCreate(List<SqlNode> operands) {
1084  // if there is only 1 Operand, the code will be creating 'defaults'
1085  return (operands.size() == 1);
1086  }
1087  }
1088 
1089  public static class LTrim extends LeftRightTrim {
1090  public LTrim() {
1091  super("LTRIM", SqlKind.LTRIM);
1092  }
1093  }
1094  public static class RTrim extends LeftRightTrim {
1095  public RTrim() {
1096  super("RTRIM", SqlKind.RTRIM);
1097  }
1098  }
1099  public static class LeftRightPad extends SqlFunction {
1100  public LeftRightPad(final String name) {
1101  super(name,
1102  SqlKind.OTHER_FUNCTION,
1103  ReturnTypes.ARG0.andThen(SqlTypeTransforms.TO_NULLABLE)
1104  .andThen(SqlTypeTransforms.TO_VARYING),
1105  null,
1106  OperandTypes.and(OperandTypes.family(SqlTypeFamily.STRING,
1107  SqlTypeFamily.INTEGER,
1108  SqlTypeFamily.STRING),
1109  new SameOperandTypeChecker(3) {
1110  @Override
1111  protected List<Integer> getOperandList(int operandCount) {
1112  return ImmutableList.of(0, 2);
1113  }
1114  }),
1115  SqlFunctionCategory.STRING);
1116  }
1117 
1118  @Override
1119  public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
1120  SqlParserPos pos,
1121  @Nullable SqlNode... operands) {
1122  assert functionQualifier == null;
1123  switch (operands.length) {
1124  case 2:
1125  operands = new SqlNode[] {
1126  operands[0], operands[1], SqlLiteral.createCharString(" ", pos)};
1127  break;
1128  case 3:
1129  if (operands[2] == null) {
1130  operands[2] = SqlLiteral.createCharString(" ", pos);
1131  }
1132  operands = new SqlNode[] {operands[0], operands[1], operands[2]};
1133  break;
1134  default:
1135  throw new IllegalArgumentException(
1136  "Invalid operand count " + Arrays.toString(operands));
1137  }
1138  return super.createCall(functionQualifier, pos, operands);
1139  }
1140 
1141  @Override
1142  public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
1143  if (!super.checkOperandTypes(callBinding, throwOnFailure)) {
1144  return false;
1145  }
1146  switch (kind) {
1147  case TRIM:
1148  return SqlTypeUtil.isCharTypeComparable(callBinding,
1149  ImmutableList.of(callBinding.operand(0), callBinding.operand(2)),
1150  throwOnFailure);
1151  default:
1152  return true;
1153  }
1154  }
1155 
1156  @Override
1157  public boolean requiresCreate(List<SqlNode> operands) {
1158  // if there are only 2 Operands, the code will be creating 'defaults'
1159  return (operands.size() == 2);
1160  }
1161  }
1162 
1163  public static class LPad extends LeftRightPad {
1164  public LPad() {
1165  super("LPAD");
1166  }
1167  }
1168  public static class RPad extends LeftRightPad {
1169  public RPad() {
1170  super("RPAD");
1171  }
1172  }
1173 
1174  public static class SplitPart extends SqlFunction {
1175  public SplitPart() {
1176  super("SPLIT_PART",
1177  SqlKind.OTHER_FUNCTION,
1178  null,
1179  null,
1180  OperandTypes.family(getSignatureFamilies()),
1182  }
1183 
1184  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1185  java.util.ArrayList<SqlTypeFamily> families =
1186  new java.util.ArrayList<SqlTypeFamily>();
1187  families.add(SqlTypeFamily.STRING);
1188  families.add(SqlTypeFamily.STRING);
1189  families.add(SqlTypeFamily.INTEGER);
1190  return families;
1191  }
1192 
1193  @Override
1194  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1195  return opBinding.getOperandType(0);
1196  }
1197  }
1198 
1199  public static class Replace extends SqlFunction {
1200  public Replace() {
1201  super("REPLACE",
1202  SqlKind.OTHER_FUNCTION,
1203  null,
1204  null,
1205  OperandTypes.family(getSignatureFamilies()),
1207  }
1208 
1209  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1210  java.util.ArrayList<SqlTypeFamily> families =
1211  new java.util.ArrayList<SqlTypeFamily>();
1212  families.add(SqlTypeFamily.STRING);
1213  families.add(SqlTypeFamily.STRING);
1214  families.add(SqlTypeFamily.STRING);
1215  return families;
1216  }
1217 
1218  @Override
1219  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1220  return opBinding.getOperandType(0);
1221  }
1222 
1223  @Override
1224  public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
1225  SqlParserPos pos,
1226  @Nullable SqlNode... operands) {
1227  assert functionQualifier == null;
1228  switch (operands.length) {
1229  case 2:
1230  operands = new SqlNode[] {
1231  operands[0], operands[1], SqlLiteral.createCharString("", pos)};
1232  break;
1233  case 3:
1234  break;
1235  default:
1236  throw new IllegalArgumentException(
1237  "Invalid operand count " + Arrays.toString(operands));
1238  }
1239  return super.createCall(functionQualifier, pos, operands);
1240  }
1241 
1242  @Override
1243  public boolean requiresCreate(List<SqlNode> operands) {
1244  // if there are only 2 Operands, the code will be creating 'defaults'
1245  return (operands.size() == 2);
1246  }
1247  }
1248  public static class Reverse extends SqlFunction {
1249  public Reverse() {
1250  super("REVERSE",
1251  SqlKind.OTHER_FUNCTION,
1252  null,
1253  null,
1254  OperandTypes.family(getSignatureFamilies()),
1256  }
1257 
1258  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1259  java.util.ArrayList<SqlTypeFamily> families =
1260  new java.util.ArrayList<SqlTypeFamily>();
1261  families.add(SqlTypeFamily.STRING);
1262  return families;
1263  }
1264 
1265  @Override
1266  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1267  return opBinding.getOperandType(0);
1268  }
1269  }
1270  public static class Repeat extends SqlFunction {
1271  public Repeat() {
1272  super("REPEAT",
1273  SqlKind.OTHER_FUNCTION,
1274  null,
1275  null,
1276  OperandTypes.family(getSignatureFamilies()),
1278  }
1279 
1280  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1281  java.util.ArrayList<SqlTypeFamily> families =
1282  new java.util.ArrayList<SqlTypeFamily>();
1283  families.add(SqlTypeFamily.STRING);
1284  families.add(SqlTypeFamily.INTEGER);
1285  return families;
1286  }
1287 
1288  @Override
1289  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1290  return opBinding.getOperandType(0);
1291  }
1292  }
1293 
1294  public static class RegexpReplace extends SqlFunction {
1295  public RegexpReplace() {
1296  super("REGEXP_REPLACE",
1297  SqlKind.OTHER_FUNCTION,
1298  null,
1299  null,
1300  OperandTypes.family(getSignatureFamilies()),
1302  }
1303 
1304  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1305  java.util.ArrayList<SqlTypeFamily> families =
1306  new java.util.ArrayList<SqlTypeFamily>();
1307  families.add(SqlTypeFamily.STRING);
1308  families.add(SqlTypeFamily.STRING);
1309  families.add(SqlTypeFamily.STRING);
1310  families.add(SqlTypeFamily.INTEGER);
1311  families.add(SqlTypeFamily.INTEGER);
1312  families.add(SqlTypeFamily.STRING);
1313  return families;
1314  }
1315 
1316  @Override
1317  public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
1318  SqlParserPos pos,
1319  @Nullable SqlNode... operands) {
1320  assert functionQualifier == null;
1321  final int num_operands = operands.length;
1322  if (num_operands < 2 || num_operands > 6) {
1323  throw new IllegalArgumentException(
1324  "Invalid operand count " + Arrays.toString(operands));
1325  }
1326  SqlNode[] new_operands = new SqlNode[6];
1327  // operand string
1328  new_operands[0] = operands[0];
1329  // pattern
1330  new_operands[1] = operands[1];
1331  // replacement
1332  if (num_operands < 3 || operands[2] == null) {
1333  new_operands[2] = SqlLiteral.createCharString("", pos);
1334  } else {
1335  new_operands[2] = operands[2];
1336  }
1337  // position
1338  if (num_operands < 4 || operands[3] == null) {
1339  new_operands[3] = SqlLiteral.createExactNumeric("1", pos);
1340  } else {
1341  new_operands[3] = operands[3];
1342  }
1343  // occurrence
1344  if (num_operands < 5 || operands[4] == null) {
1345  new_operands[4] = SqlLiteral.createExactNumeric("0", pos);
1346  } else {
1347  new_operands[4] = operands[4];
1348  }
1349  // parameters
1350  if (num_operands < 6 || operands[5] == null) {
1351  new_operands[5] = SqlLiteral.createCharString("c", pos);
1352  } else {
1353  new_operands[5] = operands[5];
1354  }
1355  return super.createCall(functionQualifier, pos, new_operands);
1356  }
1357 
1358  @Override
1359  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1360  return opBinding.getOperandType(0);
1361  }
1362  }
1363 
1364  public static class RegexpSubstr extends SqlFunction {
1365  public RegexpSubstr() {
1366  super("REGEXP_SUBSTR",
1367  SqlKind.OTHER_FUNCTION,
1368  null,
1369  null,
1370  OperandTypes.family(getSignatureFamilies()),
1372  }
1373 
1374  public RegexpSubstr(final String alias) {
1375  super(alias,
1376  SqlKind.OTHER_FUNCTION,
1377  null,
1378  null,
1379  OperandTypes.family(getSignatureFamilies()),
1380  SqlFunctionCategory.SYSTEM);
1381  }
1382 
1383  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1384  java.util.ArrayList<SqlTypeFamily> families =
1385  new java.util.ArrayList<SqlTypeFamily>();
1386  families.add(SqlTypeFamily.STRING);
1387  families.add(SqlTypeFamily.STRING);
1388  families.add(SqlTypeFamily.INTEGER);
1389  families.add(SqlTypeFamily.INTEGER);
1390  families.add(SqlTypeFamily.STRING);
1391  families.add(SqlTypeFamily.INTEGER);
1392  return families;
1393  }
1394 
1395  @Override
1396  public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
1397  SqlParserPos pos,
1398  @Nullable SqlNode... operands) {
1399  assert functionQualifier == null;
1400  final int num_operands = operands.length;
1401  if (num_operands < 2 || num_operands > 6) {
1402  throw new IllegalArgumentException(
1403  "Invalid operand count " + Arrays.toString(operands));
1404  }
1405  SqlNode[] new_operands = new SqlNode[6];
1406 
1407  // operand string (required)
1408  new_operands[0] = operands[0];
1409  // pattern (required)
1410  new_operands[1] = operands[1];
1411  // start position
1412  if (num_operands < 3 || operands[2] == null) {
1413  new_operands[2] = SqlLiteral.createExactNumeric("1", pos);
1414  } else {
1415  new_operands[2] = operands[2];
1416  }
1417  // match occurrence
1418  if (num_operands < 4 || operands[3] == null) {
1419  new_operands[3] = SqlLiteral.createExactNumeric("1", pos);
1420  } else {
1421  new_operands[3] = operands[3];
1422  }
1423  // regex params (default 'c' = case sensitive)
1424  if (num_operands < 5 || operands[4] == null) {
1425  new_operands[4] = SqlLiteral.createCharString("c", pos);
1426  } else {
1427  new_operands[4] = operands[4];
1428  }
1429  // Sub-match occurrence, valid with regex param 'e'
1430  if (num_operands < 6 || operands[5] == null) {
1431  new_operands[5] = SqlLiteral.createExactNumeric("1", pos);
1432  } else {
1433  new_operands[5] = operands[5];
1434  }
1435  return super.createCall(functionQualifier, pos, new_operands);
1436  }
1437 
1438  @Override
1439  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1440  return opBinding.getOperandType(0);
1441  }
1442  }
1443 
1444  public static class RegexpMatch extends RegexpSubstr {
1445  public RegexpMatch() {
1446  super("REGEXP_MATCH");
1447  }
1448  }
1449 
1450  public static class RegexpCount extends SqlFunction {
1451  public RegexpCount() {
1452  super("REGEXP_COUNT",
1453  SqlKind.OTHER_FUNCTION,
1454  null,
1455  null,
1456  OperandTypes.family(getSignatureFamilies()),
1458  }
1459 
1460  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1461  java.util.ArrayList<SqlTypeFamily> families =
1462  new java.util.ArrayList<SqlTypeFamily>();
1463  families.add(SqlTypeFamily.STRING);
1464  families.add(SqlTypeFamily.STRING);
1465  families.add(SqlTypeFamily.INTEGER);
1466  families.add(SqlTypeFamily.STRING);
1467  return families;
1468  }
1469 
1470  @Override
1471  public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
1472  SqlParserPos pos,
1473  @Nullable SqlNode... operands) {
1474  assert functionQualifier == null;
1475  final int num_operands = operands.length;
1476  if (num_operands < 2 || num_operands > 4) {
1477  throw new IllegalArgumentException(
1478  "Invalid operand count " + Arrays.toString(operands));
1479  }
1480  SqlNode[] new_operands = new SqlNode[4];
1481  // operand string
1482  new_operands[0] = operands[0];
1483  // pattern
1484  new_operands[1] = operands[1];
1485  // position
1486  if (num_operands < 3 || operands[2] == null) {
1487  new_operands[2] = SqlLiteral.createExactNumeric("1", pos);
1488  } else {
1489  new_operands[2] = operands[2];
1490  }
1491  // parameters
1492  if (num_operands < 4 || operands[3] == null) {
1493  new_operands[3] = SqlLiteral.createCharString("c", pos);
1494  } else {
1495  new_operands[3] = operands[3];
1496  }
1497  return super.createCall(functionQualifier, pos, new_operands);
1498  }
1499 
1500  @Override
1501  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1502  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1503  RelDataType dataType = typeFactory.createSqlType(SqlTypeName.BIGINT);
1504  return typeFactory.createTypeWithNullability(dataType, true);
1505  }
1506  }
1507 
1508  public static class Base64Encode extends SqlFunction {
1509  public Base64Encode() {
1510  super("BASE64_ENCODE",
1511  SqlKind.OTHER_FUNCTION,
1512  null,
1513  null,
1514  OperandTypes.family(getSignatureFamilies()),
1516  }
1517 
1518  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1519  java.util.ArrayList<SqlTypeFamily> families =
1520  new java.util.ArrayList<SqlTypeFamily>();
1521  families.add(SqlTypeFamily.STRING);
1522  return families;
1523  }
1524 
1525  @Override
1526  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1527  return opBinding.getOperandType(0);
1528  }
1529  }
1530 
1531  public static class Base64Decode extends SqlFunction {
1532  public Base64Decode() {
1533  super("BASE64_DECODE",
1534  SqlKind.OTHER_FUNCTION,
1535  null,
1536  null,
1537  OperandTypes.family(getSignatureFamilies()),
1539  }
1540 
1541  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1542  java.util.ArrayList<SqlTypeFamily> families =
1543  new java.util.ArrayList<SqlTypeFamily>();
1544  families.add(SqlTypeFamily.STRING);
1545  return families;
1546  }
1547 
1548  @Override
1549  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1550  return opBinding.getOperandType(0);
1551  }
1552  }
1553 
1554  public static class UrlEncode extends SqlFunction {
1555  public UrlEncode() {
1556  super("URL_ENCODE",
1557  SqlKind.OTHER_FUNCTION,
1558  null,
1559  null,
1560  OperandTypes.family(getSignatureFamilies()),
1562  }
1563 
1564  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1565  java.util.ArrayList<SqlTypeFamily> families =
1566  new java.util.ArrayList<SqlTypeFamily>();
1567  families.add(SqlTypeFamily.STRING);
1568  return families;
1569  }
1570 
1571  @Override
1572  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1573  return opBinding.getOperandType(0);
1574  }
1575  }
1576 
1577  public static class UrlDecode extends SqlFunction {
1578  public UrlDecode() {
1579  super("URL_DECODE",
1580  SqlKind.OTHER_FUNCTION,
1581  null,
1582  null,
1583  OperandTypes.family(getSignatureFamilies()),
1585  }
1586 
1587  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1588  java.util.ArrayList<SqlTypeFamily> families =
1589  new java.util.ArrayList<SqlTypeFamily>();
1590  families.add(SqlTypeFamily.STRING);
1591  return families;
1592  }
1593 
1594  @Override
1595  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1596  return opBinding.getOperandType(0);
1597  }
1598  }
1599 
1600  public static class JarowinklerSimilarity extends SqlFunction {
1602  super("JAROWINKLER_SIMILARITY",
1603  SqlKind.OTHER_FUNCTION,
1604  null,
1605  null,
1606  OperandTypes.family(getSignatureFamilies()),
1608  }
1609 
1610  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1611  java.util.ArrayList<SqlTypeFamily> families =
1612  new java.util.ArrayList<SqlTypeFamily>();
1613  families.add(SqlTypeFamily.STRING);
1614  families.add(SqlTypeFamily.STRING);
1615  return families;
1616  }
1617 
1618  @Override
1619  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1620  assert opBinding.getOperandCount() == 2;
1621  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1622  RelDataType dataType = typeFactory.createSqlType(SqlTypeName.BIGINT);
1623  return typeFactory.createTypeWithNullability(dataType, true);
1624  }
1625  }
1626 
1627  public static class LevenshteinDistance extends SqlFunction {
1629  super("LEVENSHTEIN_DISTANCE",
1630  SqlKind.OTHER_FUNCTION,
1631  null,
1632  null,
1633  OperandTypes.family(getSignatureFamilies()),
1635  }
1636 
1637  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1638  java.util.ArrayList<SqlTypeFamily> families =
1639  new java.util.ArrayList<SqlTypeFamily>();
1640  families.add(SqlTypeFamily.STRING);
1641  families.add(SqlTypeFamily.STRING);
1642  return families;
1643  }
1644 
1645  @Override
1646  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1647  assert opBinding.getOperandCount() == 2;
1648  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1649  RelDataType dataType = typeFactory.createSqlType(SqlTypeName.BIGINT);
1650  return typeFactory.createTypeWithNullability(dataType, true);
1651  }
1652  }
1653 
1654  public static class TryCast extends SqlFunction {
1655  //~ Instance fields --------------------------------------------------------
1656 
1657  public TryCast() {
1658  super("TRY_CAST",
1659  SqlKind.OTHER_FUNCTION,
1660  null,
1661  InferTypes.FIRST_KNOWN,
1662  null,
1663  SqlFunctionCategory.SYSTEM);
1664  }
1665 
1666  //~ Methods ----------------------------------------------------------------
1667 
1668  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1669  assert opBinding.getOperandCount() == 2;
1670  RelDataType ret = opBinding.getOperandType(1);
1671  RelDataType firstType = opBinding.getOperandType(0);
1672  ret = opBinding.getTypeFactory().createTypeWithNullability(
1673  ret, firstType.isNullable());
1674  if (opBinding instanceof SqlCallBinding) {
1675  SqlCallBinding callBinding = (SqlCallBinding) opBinding;
1676  SqlNode operand0 = callBinding.operand(0);
1677 
1678  // dynamic parameters and null constants need their types assigned
1679  // to them using the type they are casted to.
1680  if (((operand0 instanceof SqlLiteral)
1681  && (((SqlLiteral) operand0).getValue() == null))
1682  || (operand0 instanceof SqlDynamicParam)) {
1683  final SqlValidatorImpl validator =
1684  (SqlValidatorImpl) callBinding.getValidator();
1685  validator.setValidatedNodeType(operand0, ret);
1686  }
1687  }
1688  return ret;
1689  }
1690 
1691  public String getSignatureTemplate(final int operandsCount) {
1692  assert operandsCount == 2;
1693  return "{0}({1} AS {2})";
1694  }
1695 
1696  public SqlOperandCountRange getOperandCountRange() {
1697  return SqlOperandCountRanges.of(2);
1698  }
1699 
1705  public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
1706  final SqlNode left = callBinding.operand(0);
1707  final SqlNode right = callBinding.operand(1);
1708  if (SqlUtil.isNullLiteral(left, false) || left instanceof SqlDynamicParam) {
1709  return true;
1710  }
1711  RelDataType validatedNodeType =
1712  callBinding.getValidator().getValidatedNodeType(left);
1713  RelDataType returnType =
1714  callBinding.getValidator().deriveType(callBinding.getScope(), right);
1715  if (!SqlTypeUtil.canCastFrom(returnType, validatedNodeType, true)) {
1716  if (throwOnFailure) {
1717  throw callBinding.newError(RESOURCE.cannotCastValue(
1718  validatedNodeType.toString(), returnType.toString()));
1719  }
1720  return false;
1721  }
1722  if (SqlTypeUtil.areCharacterSetsMismatched(validatedNodeType, returnType)) {
1723  if (throwOnFailure) {
1724  // Include full type string to indicate character
1725  // set mismatch.
1726  throw callBinding.newError(RESOURCE.cannotCastValue(
1727  validatedNodeType.getFullTypeString(), returnType.getFullTypeString()));
1728  }
1729  return false;
1730  }
1731  return true;
1732  }
1733 
1734  public SqlSyntax getSyntax() {
1735  return SqlSyntax.FUNCTION;
1736  }
1737 
1738  public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
1739  assert call.operandCount() == 2;
1740  final SqlWriter.Frame frame = writer.startFunCall(getName());
1741  call.operand(0).unparse(writer, 0, 0);
1742  writer.sep("AS");
1743  if (call.operand(1) instanceof SqlIntervalQualifier) {
1744  writer.sep("INTERVAL");
1745  }
1746  call.operand(1).unparse(writer, 0, 0);
1747  writer.endFunCall(frame);
1748  }
1749  }
1750 
1751  public static class Hash extends SqlFunction {
1752  public Hash() {
1753  super("HASH",
1754  SqlKind.OTHER_FUNCTION,
1755  null,
1756  null,
1757  OperandTypes.family(getSignatureFamilies()),
1758  SqlFunctionCategory.SYSTEM);
1759  }
1760 
1761  private static java.util.List<SqlTypeFamily> getSignatureFamilies() {
1762  java.util.ArrayList<SqlTypeFamily> families =
1763  new java.util.ArrayList<SqlTypeFamily>();
1764  // Todo(todd): Support any input type for HASH function
1765  // families.add(SqlTypeFamily.ANY);
1766  families.add(SqlTypeFamily.STRING);
1767  return families;
1768  }
1769 
1770  @Override
1771  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1772  assert opBinding.getOperandCount() == 1;
1773  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1774  return typeFactory.createTypeWithNullability(
1775  typeFactory.createSqlType(SqlTypeName.BIGINT),
1776  opBinding.getOperandType(0).isNullable());
1777  }
1778  }
1779 
1780  public static class Likely extends SqlFunction {
1781  public Likely() {
1782  super("LIKELY",
1783  SqlKind.OTHER_FUNCTION,
1784  null,
1785  null,
1786  OperandTypes.BOOLEAN,
1787  SqlFunctionCategory.SYSTEM);
1788  }
1789 
1790  @Override
1791  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1792  return opBinding.getOperandType(0);
1793  }
1794  }
1795 
1796  public static class Unlikely extends SqlFunction {
1797  public Unlikely() {
1798  super("UNLIKELY",
1799  SqlKind.OTHER_FUNCTION,
1800  null,
1801  null,
1802  OperandTypes.BOOLEAN,
1803  SqlFunctionCategory.SYSTEM);
1804  }
1805 
1806  @Override
1807  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1808  return opBinding.getOperandType(0);
1809  }
1810  }
1811 
1812  public static class Sign extends SqlFunction {
1813  public Sign() {
1814  super("SIGN",
1815  SqlKind.OTHER_FUNCTION,
1816  null,
1817  null,
1818  OperandTypes.NUMERIC,
1819  SqlFunctionCategory.NUMERIC);
1820  }
1821 
1822  @Override
1823  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1824  return opBinding.getOperandType(0);
1825  }
1826  }
1827 
1828  static class Truncate extends SqlFunction {
1830  super("TRUNCATE",
1831  SqlKind.OTHER_FUNCTION,
1832  null,
1833  null,
1834  OperandTypes.family(signature()),
1835  SqlFunctionCategory.NUMERIC);
1836  }
1837 
1838  @Override
1839  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1840  assert opBinding.getOperandCount() == 2;
1841  return opBinding.getOperandType(0);
1842  }
1843 
1844  private static java.util.List<SqlTypeFamily> signature() {
1845  java.util.List<SqlTypeFamily> truncate_sig =
1846  new java.util.ArrayList<SqlTypeFamily>();
1847  truncate_sig.add(SqlTypeFamily.NUMERIC);
1848  truncate_sig.add(SqlTypeFamily.INTEGER);
1849  return truncate_sig;
1850  }
1851  }
1852 
1853  static class ST_IsEmpty extends SqlFunction {
1855  super("ST_IsEmpty",
1856  SqlKind.OTHER_FUNCTION,
1857  null,
1858  null,
1859  OperandTypes.family(signature()),
1860  SqlFunctionCategory.SYSTEM);
1861  }
1862 
1863  @Override
1864  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1865  assert opBinding.getOperandCount() == 1;
1866  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1867  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
1868  }
1869 
1870  private static java.util.List<SqlTypeFamily> signature() {
1871  java.util.List<SqlTypeFamily> st_isempty_sig =
1872  new java.util.ArrayList<SqlTypeFamily>();
1873  st_isempty_sig.add(SqlTypeFamily.ANY);
1874  return st_isempty_sig;
1875  }
1876  }
1877 
1878  static class ST_IsValid extends SqlFunction {
1880  super("ST_IsValid",
1881  SqlKind.OTHER_FUNCTION,
1882  null,
1883  null,
1884  OperandTypes.family(signature()),
1885  SqlFunctionCategory.SYSTEM);
1886  }
1887 
1888  @Override
1889  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1890  assert opBinding.getOperandCount() == 1;
1891  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1892  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
1893  }
1894 
1895  private static java.util.List<SqlTypeFamily> signature() {
1896  java.util.List<SqlTypeFamily> st_isvalid_sig =
1897  new java.util.ArrayList<SqlTypeFamily>();
1898  st_isvalid_sig.add(SqlTypeFamily.ANY);
1899  return st_isvalid_sig;
1900  }
1901  }
1902 
1903  static class ST_Contains extends SqlFunction {
1905  super("ST_Contains",
1906  SqlKind.OTHER_FUNCTION,
1907  null,
1908  null,
1909  OperandTypes.family(signature()),
1910  SqlFunctionCategory.SYSTEM);
1911  }
1912 
1913  @Override
1914  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1915  assert opBinding.getOperandCount() == 2;
1916  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1917  return typeFactory.createTypeWithNullability(
1918  typeFactory.createSqlType(SqlTypeName.BOOLEAN),
1919  opBinding.getOperandType(0).isNullable()
1920  || opBinding.getOperandType(1).isNullable());
1921  }
1922 
1923  private static java.util.List<SqlTypeFamily> signature() {
1924  java.util.List<SqlTypeFamily> st_contains_sig =
1925  new java.util.ArrayList<SqlTypeFamily>();
1926  st_contains_sig.add(SqlTypeFamily.ANY);
1927  st_contains_sig.add(SqlTypeFamily.ANY);
1928  return st_contains_sig;
1929  }
1930  }
1931 
1932  static class ST_Equals extends SqlFunction {
1934  super("ST_Equals",
1935  SqlKind.OTHER_FUNCTION,
1936  null,
1937  null,
1938  OperandTypes.family(signature()),
1939  SqlFunctionCategory.SYSTEM);
1940  }
1941 
1942  @Override
1943  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1944  assert opBinding.getOperandCount() == 2;
1945  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1946  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
1947  }
1948 
1949  private static java.util.List<SqlTypeFamily> signature() {
1950  java.util.List<SqlTypeFamily> st_equals_sig =
1951  new java.util.ArrayList<SqlTypeFamily>();
1952  st_equals_sig.add(SqlTypeFamily.ANY);
1953  st_equals_sig.add(SqlTypeFamily.ANY);
1954  return st_equals_sig;
1955  }
1956  }
1957 
1958  static class ST_Intersects extends SqlFunction {
1960  super("ST_Intersects",
1961  SqlKind.OTHER_FUNCTION,
1962  null,
1963  null,
1964  OperandTypes.family(signature()),
1965  SqlFunctionCategory.SYSTEM);
1966  }
1967 
1968  @Override
1969  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1970  assert opBinding.getOperandCount() == 2;
1971  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
1972  return typeFactory.createTypeWithNullability(
1973  typeFactory.createSqlType(SqlTypeName.BOOLEAN),
1974  opBinding.getOperandType(0).isNullable()
1975  || opBinding.getOperandType(1).isNullable());
1976  }
1977 
1978  private static java.util.List<SqlTypeFamily> signature() {
1979  java.util.List<SqlTypeFamily> st_intersects_sig =
1980  new java.util.ArrayList<SqlTypeFamily>();
1981  st_intersects_sig.add(SqlTypeFamily.ANY);
1982  st_intersects_sig.add(SqlTypeFamily.ANY);
1983  return st_intersects_sig;
1984  }
1985  }
1986 
1987  static class ST_IntersectsBox extends SqlFunction {
1989  super("ST_IntersectsBox",
1990  SqlKind.OTHER_FUNCTION,
1991  null,
1992  null,
1993  OperandTypes.family(signature()),
1994  SqlFunctionCategory.SYSTEM);
1995  }
1996 
1997  @Override
1998  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
1999  assert opBinding.getOperandCount() == 2;
2000  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2001  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
2002  }
2003 
2004  private static java.util.List<SqlTypeFamily> signature() {
2005  java.util.List<SqlTypeFamily> st_intersect_box_sig =
2006  new java.util.ArrayList<SqlTypeFamily>();
2007  st_intersect_box_sig.add(SqlTypeFamily.ANY);
2008  st_intersect_box_sig.add(SqlTypeFamily.ANY);
2009  return st_intersect_box_sig;
2010  }
2011  }
2012 
2013  static class ST_Approx_Overlaps extends SqlFunction {
2015  super("ST_Approx_Overlaps",
2016  SqlKind.OTHER_FUNCTION,
2017  null,
2018  null,
2019  OperandTypes.family(signature()),
2020  SqlFunctionCategory.SYSTEM);
2021  }
2022 
2023  @Override
2024  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2025  assert opBinding.getOperandCount() == 2;
2026  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2027  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
2028  }
2029 
2030  private static java.util.List<SqlTypeFamily> signature() {
2031  java.util.List<SqlTypeFamily> st_intersect_box_sig =
2032  new java.util.ArrayList<SqlTypeFamily>();
2033  st_intersect_box_sig.add(SqlTypeFamily.ANY);
2034  st_intersect_box_sig.add(SqlTypeFamily.ANY);
2035  return st_intersect_box_sig;
2036  }
2037  }
2038 
2039  static class ST_Disjoint extends SqlFunction {
2041  super("ST_Disjoint",
2042  SqlKind.OTHER_FUNCTION,
2043  null,
2044  null,
2045  OperandTypes.family(signature()),
2046  SqlFunctionCategory.SYSTEM);
2047  }
2048 
2049  @Override
2050  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2051  assert opBinding.getOperandCount() == 2;
2052  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2053  return typeFactory.createTypeWithNullability(
2054  typeFactory.createSqlType(SqlTypeName.BOOLEAN),
2055  opBinding.getOperandType(0).isNullable()
2056  || opBinding.getOperandType(1).isNullable());
2057  }
2058 
2059  private static java.util.List<SqlTypeFamily> signature() {
2060  java.util.List<SqlTypeFamily> st_disjoint_sig =
2061  new java.util.ArrayList<SqlTypeFamily>();
2062  st_disjoint_sig.add(SqlTypeFamily.ANY);
2063  st_disjoint_sig.add(SqlTypeFamily.ANY);
2064  return st_disjoint_sig;
2065  }
2066  }
2067 
2068  static class ST_Within extends SqlFunction {
2070  super("ST_Within",
2071  SqlKind.OTHER_FUNCTION,
2072  null,
2073  null,
2074  OperandTypes.family(signature()),
2075  SqlFunctionCategory.SYSTEM);
2076  }
2077 
2078  @Override
2079  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2080  assert opBinding.getOperandCount() == 2;
2081  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2082  return typeFactory.createTypeWithNullability(
2083  typeFactory.createSqlType(SqlTypeName.BOOLEAN),
2084  opBinding.getOperandType(0).isNullable()
2085  || opBinding.getOperandType(1).isNullable());
2086  }
2087 
2088  private static java.util.List<SqlTypeFamily> signature() {
2089  java.util.List<SqlTypeFamily> st_within_sig =
2090  new java.util.ArrayList<SqlTypeFamily>();
2091  st_within_sig.add(SqlTypeFamily.ANY);
2092  st_within_sig.add(SqlTypeFamily.ANY);
2093  return st_within_sig;
2094  }
2095  }
2096 
2097  static class ST_DWithin extends SqlFunction {
2099  super("ST_DWithin",
2100  SqlKind.OTHER_FUNCTION,
2101  null,
2102  null,
2103  OperandTypes.family(signature()),
2104  SqlFunctionCategory.SYSTEM);
2105  }
2106 
2107  @Override
2108  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2109  assert opBinding.getOperandCount() == 3;
2110  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2111  return typeFactory.createTypeWithNullability(
2112  typeFactory.createSqlType(SqlTypeName.BOOLEAN),
2113  opBinding.getOperandType(0).isNullable()
2114  || opBinding.getOperandType(1).isNullable()
2115  || opBinding.getOperandType(2).isNullable());
2116  }
2117 
2118  private static java.util.List<SqlTypeFamily> signature() {
2119  java.util.List<SqlTypeFamily> st_dwithin_sig =
2120  new java.util.ArrayList<SqlTypeFamily>();
2121  st_dwithin_sig.add(SqlTypeFamily.ANY);
2122  st_dwithin_sig.add(SqlTypeFamily.ANY);
2123  st_dwithin_sig.add(SqlTypeFamily.NUMERIC);
2124  return st_dwithin_sig;
2125  }
2126  }
2127 
2128  static class ST_DFullyWithin extends SqlFunction {
2130  super("ST_DFullyWithin",
2131  SqlKind.OTHER_FUNCTION,
2132  null,
2133  null,
2134  OperandTypes.family(signature()),
2135  SqlFunctionCategory.SYSTEM);
2136  }
2137 
2138  @Override
2139  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2140  assert opBinding.getOperandCount() == 3;
2141  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2142  return typeFactory.createTypeWithNullability(
2143  typeFactory.createSqlType(SqlTypeName.BOOLEAN),
2144  opBinding.getOperandType(0).isNullable()
2145  || opBinding.getOperandType(1).isNullable()
2146  || opBinding.getOperandType(2).isNullable());
2147  }
2148 
2149  private static java.util.List<SqlTypeFamily> signature() {
2150  java.util.List<SqlTypeFamily> st_dwithin_sig =
2151  new java.util.ArrayList<SqlTypeFamily>();
2152  st_dwithin_sig.add(SqlTypeFamily.ANY);
2153  st_dwithin_sig.add(SqlTypeFamily.ANY);
2154  st_dwithin_sig.add(SqlTypeFamily.NUMERIC);
2155  return st_dwithin_sig;
2156  }
2157  }
2158 
2159  static class ST_Distance extends SqlFunction {
2161  super("ST_Distance",
2162  SqlKind.OTHER_FUNCTION,
2163  null,
2164  null,
2165  OperandTypes.family(signature()),
2166  SqlFunctionCategory.SYSTEM);
2167  }
2168 
2169  @Override
2170  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2171  assert opBinding.getOperandCount() == 2;
2172  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2173  return typeFactory.createTypeWithNullability(
2174  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2175  opBinding.getOperandType(0).isNullable()
2176  || opBinding.getOperandType(1).isNullable());
2177  }
2178 
2179  private static java.util.List<SqlTypeFamily> signature() {
2180  java.util.List<SqlTypeFamily> st_distance_sig =
2181  new java.util.ArrayList<SqlTypeFamily>();
2182  st_distance_sig.add(SqlTypeFamily.ANY);
2183  st_distance_sig.add(SqlTypeFamily.ANY);
2184  return st_distance_sig;
2185  }
2186  }
2187 
2188  static class ST_MaxDistance extends SqlFunction {
2190  super("ST_MaxDistance",
2191  SqlKind.OTHER_FUNCTION,
2192  null,
2193  null,
2194  OperandTypes.family(signature()),
2195  SqlFunctionCategory.SYSTEM);
2196  }
2197 
2198  @Override
2199  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2200  assert opBinding.getOperandCount() == 2;
2201  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2202  return typeFactory.createTypeWithNullability(
2203  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2204  opBinding.getOperandType(0).isNullable()
2205  || opBinding.getOperandType(1).isNullable());
2206  }
2207 
2208  private static java.util.List<SqlTypeFamily> signature() {
2209  java.util.List<SqlTypeFamily> st_maxdistance_sig =
2210  new java.util.ArrayList<SqlTypeFamily>();
2211  st_maxdistance_sig.add(SqlTypeFamily.ANY);
2212  st_maxdistance_sig.add(SqlTypeFamily.ANY);
2213  return st_maxdistance_sig;
2214  }
2215  }
2216 
2217  static class ST_GeogFromText extends SqlFunction {
2219  super("ST_GeogFromText",
2220  SqlKind.OTHER_FUNCTION,
2221  null,
2222  null,
2223  OperandTypes.or(OperandTypes.family(SqlTypeFamily.ANY),
2224  OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER)),
2225  SqlFunctionCategory.SYSTEM);
2226  }
2227 
2228  @Override
2229  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2230  assert opBinding.getOperandCount() == 1;
2231  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2232  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2233  }
2234  }
2235 
2236  static class ST_GeomFromText extends SqlFunction {
2238  super("ST_GeomFromText",
2239  SqlKind.OTHER_FUNCTION,
2240  null,
2241  null,
2242  OperandTypes.or(OperandTypes.family(SqlTypeFamily.ANY),
2243  OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER)),
2244  SqlFunctionCategory.SYSTEM);
2245  }
2246 
2247  @Override
2248  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2249  assert opBinding.getOperandCount() == 1;
2250  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2251  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2252  }
2253  }
2254 
2255  static class ST_Transform extends SqlFunction {
2257  super("ST_Transform",
2258  SqlKind.OTHER_FUNCTION,
2259  null,
2260  null,
2261  OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER),
2262  SqlFunctionCategory.SYSTEM);
2263  }
2264 
2265  @Override
2266  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2267  assert opBinding.getOperandCount() == 1;
2268  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2269  return typeFactory.createTypeWithNullability(
2270  typeFactory.createSqlType(SqlTypeName.INTEGER),
2271  opBinding.getOperandType(0).isNullable());
2272  }
2273  }
2274 
2275  static class ST_X extends SqlFunction {
2276  ST_X() {
2277  super("ST_X",
2278  SqlKind.OTHER_FUNCTION,
2279  null,
2280  null,
2281  OperandTypes.family(SqlTypeFamily.ANY),
2282  SqlFunctionCategory.SYSTEM);
2283  }
2284 
2285  @Override
2286  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2287  assert opBinding.getOperandCount() == 1;
2288  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2289  return typeFactory.createTypeWithNullability(
2290  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2291  opBinding.getOperandType(0).isNullable());
2292  }
2293  }
2294 
2295  static class ST_Y extends SqlFunction {
2296  ST_Y() {
2297  super("ST_Y",
2298  SqlKind.OTHER_FUNCTION,
2299  null,
2300  null,
2301  OperandTypes.family(SqlTypeFamily.ANY),
2302  SqlFunctionCategory.SYSTEM);
2303  }
2304 
2305  @Override
2306  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2307  assert opBinding.getOperandCount() == 1;
2308  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2309  return typeFactory.createTypeWithNullability(
2310  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2311  opBinding.getOperandType(0).isNullable());
2312  }
2313  }
2314 
2315  static class ST_XMin extends SqlFunction {
2317  super("ST_XMin",
2318  SqlKind.OTHER_FUNCTION,
2319  null,
2320  null,
2321  OperandTypes.family(SqlTypeFamily.ANY),
2322  SqlFunctionCategory.SYSTEM);
2323  }
2324 
2325  @Override
2326  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2327  assert opBinding.getOperandCount() == 1;
2328  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2329  return typeFactory.createTypeWithNullability(
2330  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2331  opBinding.getOperandType(0).isNullable());
2332  }
2333  }
2334 
2335  static class ST_XMax extends SqlFunction {
2337  super("ST_XMax",
2338  SqlKind.OTHER_FUNCTION,
2339  null,
2340  null,
2341  OperandTypes.family(SqlTypeFamily.ANY),
2342  SqlFunctionCategory.SYSTEM);
2343  }
2344 
2345  @Override
2346  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2347  assert opBinding.getOperandCount() == 1;
2348  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2349  return typeFactory.createTypeWithNullability(
2350  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2351  opBinding.getOperandType(0).isNullable());
2352  }
2353  }
2354 
2355  static class ST_YMin extends SqlFunction {
2357  super("ST_YMin",
2358  SqlKind.OTHER_FUNCTION,
2359  null,
2360  null,
2361  OperandTypes.family(SqlTypeFamily.ANY),
2362  SqlFunctionCategory.SYSTEM);
2363  }
2364 
2365  @Override
2366  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2367  assert opBinding.getOperandCount() == 1;
2368  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2369  return typeFactory.createTypeWithNullability(
2370  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2371  opBinding.getOperandType(0).isNullable());
2372  }
2373  }
2374 
2375  static class ST_YMax extends SqlFunction {
2377  super("ST_YMax",
2378  SqlKind.OTHER_FUNCTION,
2379  null,
2380  null,
2381  OperandTypes.family(SqlTypeFamily.ANY),
2382  SqlFunctionCategory.SYSTEM);
2383  }
2384 
2385  @Override
2386  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2387  assert opBinding.getOperandCount() == 1;
2388  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2389  return typeFactory.createTypeWithNullability(
2390  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2391  opBinding.getOperandType(0).isNullable());
2392  }
2393  }
2394 
2395  static class ST_PointN extends SqlFunction {
2397  super("ST_PointN",
2398  SqlKind.OTHER_FUNCTION,
2399  null,
2400  null,
2401  OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER),
2402  SqlFunctionCategory.SYSTEM);
2403  }
2404 
2405  @Override
2406  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2407  assert opBinding.getOperandCount() == 1;
2408  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2409  return typeFactory.createTypeWithNullability(
2410  typeFactory.createSqlType(SqlTypeName.INTEGER),
2411  opBinding.getOperandType(0).isNullable());
2412  }
2413  }
2414 
2415  static class ST_EndPoint extends SqlFunction {
2417  super("ST_EndPoint",
2418  SqlKind.OTHER_FUNCTION,
2419  null,
2420  null,
2421  OperandTypes.family(SqlTypeFamily.ANY),
2422  SqlFunctionCategory.SYSTEM);
2423  }
2424 
2425  @Override
2426  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2427  assert opBinding.getOperandCount() == 1;
2428  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2429  return typeFactory.createTypeWithNullability(
2430  typeFactory.createSqlType(SqlTypeName.INTEGER),
2431  opBinding.getOperandType(0).isNullable());
2432  }
2433  }
2434 
2435  static class ST_StartPoint extends SqlFunction {
2437  super("ST_StartPoint",
2438  SqlKind.OTHER_FUNCTION,
2439  null,
2440  null,
2441  OperandTypes.family(SqlTypeFamily.ANY),
2442  SqlFunctionCategory.SYSTEM);
2443  }
2444 
2445  @Override
2446  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2447  assert opBinding.getOperandCount() == 1;
2448  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2449  return typeFactory.createTypeWithNullability(
2450  typeFactory.createSqlType(SqlTypeName.INTEGER),
2451  opBinding.getOperandType(0).isNullable());
2452  }
2453  }
2454 
2455  static class ST_Length extends SqlFunction {
2457  super("ST_Length",
2458  SqlKind.OTHER_FUNCTION,
2459  null,
2460  null,
2461  OperandTypes.family(SqlTypeFamily.ANY),
2462  SqlFunctionCategory.SYSTEM);
2463  }
2464 
2465  @Override
2466  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2467  assert opBinding.getOperandCount() == 1;
2468  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2469  return typeFactory.createTypeWithNullability(
2470  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2471  opBinding.getOperandType(0).isNullable());
2472  }
2473  }
2474 
2475  static class ST_Perimeter extends SqlFunction {
2477  super("ST_Perimeter",
2478  SqlKind.OTHER_FUNCTION,
2479  null,
2480  null,
2481  OperandTypes.family(SqlTypeFamily.ANY),
2482  SqlFunctionCategory.SYSTEM);
2483  }
2484 
2485  @Override
2486  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2487  assert opBinding.getOperandCount() == 1;
2488  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2489  return typeFactory.createTypeWithNullability(
2490  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2491  opBinding.getOperandType(0).isNullable());
2492  }
2493  }
2494 
2495  static class ST_Area extends SqlFunction {
2497  super("ST_Area",
2498  SqlKind.OTHER_FUNCTION,
2499  null,
2500  null,
2501  OperandTypes.family(SqlTypeFamily.ANY),
2502  SqlFunctionCategory.SYSTEM);
2503  }
2504 
2505  @Override
2506  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2507  assert opBinding.getOperandCount() == 1;
2508  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2509  return typeFactory.createTypeWithNullability(
2510  typeFactory.createSqlType(SqlTypeName.DOUBLE),
2511  opBinding.getOperandType(0).isNullable());
2512  }
2513  }
2514 
2515  static class ST_NPoints extends SqlFunction {
2517  super("ST_NPoints",
2518  SqlKind.OTHER_FUNCTION,
2519  null,
2520  null,
2521  OperandTypes.family(SqlTypeFamily.ANY),
2522  SqlFunctionCategory.SYSTEM);
2523  }
2524 
2525  @Override
2526  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2527  assert opBinding.getOperandCount() == 1;
2528  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2529  return typeFactory.createTypeWithNullability(
2530  typeFactory.createSqlType(SqlTypeName.INTEGER),
2531  opBinding.getOperandType(0).isNullable());
2532  }
2533  }
2534 
2535  static class ST_NRings extends SqlFunction {
2537  super("ST_NRings",
2538  SqlKind.OTHER_FUNCTION,
2539  null,
2540  null,
2541  OperandTypes.family(SqlTypeFamily.ANY),
2542  SqlFunctionCategory.SYSTEM);
2543  }
2544 
2545  @Override
2546  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2547  assert opBinding.getOperandCount() == 1;
2548  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2549  return typeFactory.createTypeWithNullability(
2550  typeFactory.createSqlType(SqlTypeName.INTEGER),
2551  opBinding.getOperandType(0).isNullable());
2552  }
2553  }
2554 
2555  static class ST_NumGeometries extends SqlFunction {
2557  super("ST_NumGeometries",
2558  SqlKind.OTHER_FUNCTION,
2559  null,
2560  null,
2561  OperandTypes.family(SqlTypeFamily.ANY),
2562  SqlFunctionCategory.SYSTEM);
2563  }
2564 
2565  @Override
2566  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2567  assert opBinding.getOperandCount() == 1;
2568  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2569  return typeFactory.createTypeWithNullability(
2570  typeFactory.createSqlType(SqlTypeName.INTEGER),
2571  opBinding.getOperandType(0).isNullable());
2572  }
2573  }
2574 
2575  static class ST_SRID extends SqlFunction {
2577  super("ST_SRID",
2578  SqlKind.OTHER_FUNCTION,
2579  null,
2580  null,
2581  OperandTypes.family(SqlTypeFamily.ANY),
2582  SqlFunctionCategory.SYSTEM);
2583  }
2584 
2585  @Override
2586  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2587  assert opBinding.getOperandCount() == 1;
2588  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2589  return typeFactory.createTypeWithNullability(
2590  typeFactory.createSqlType(SqlTypeName.INTEGER),
2591  opBinding.getOperandType(0).isNullable());
2592  }
2593  }
2594 
2595  static class ST_SetSRID extends SqlFunction {
2597  super("ST_SetSRID",
2598  SqlKind.OTHER_FUNCTION,
2599  null,
2600  null,
2601  OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER),
2602  SqlFunctionCategory.SYSTEM);
2603  }
2604 
2605  @Override
2606  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2607  assert opBinding.getOperandCount() == 1;
2608  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2609  return typeFactory.createTypeWithNullability(
2610  typeFactory.createSqlType(SqlTypeName.INTEGER),
2611  opBinding.getOperandType(0).isNullable());
2612  }
2613  }
2614 
2615  static class ST_Point extends SqlFunction {
2617  super("ST_Point",
2618  SqlKind.OTHER_FUNCTION,
2619  null,
2620  null,
2621  OperandTypes.family(SqlTypeFamily.NUMERIC, SqlTypeFamily.NUMERIC),
2622  SqlFunctionCategory.SYSTEM);
2623  }
2624 
2625  @Override
2626  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2627  assert opBinding.getOperandCount() == 2;
2628  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2629  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2630  }
2631  }
2632 
2633  static class ST_Centroid extends SqlFunction {
2635  super("ST_Centroid",
2636  SqlKind.OTHER_FUNCTION,
2637  null,
2638  null,
2639  OperandTypes.family(signature()),
2640  SqlFunctionCategory.SYSTEM);
2641  }
2642 
2643  @Override
2644  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2645  assert opBinding.getOperandCount() == 1;
2646  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2647  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2648  }
2649 
2650  private static java.util.List<SqlTypeFamily> signature() {
2651  java.util.List<SqlTypeFamily> st_centroid_sig =
2652  new java.util.ArrayList<SqlTypeFamily>();
2653  st_centroid_sig.add(SqlTypeFamily.ANY);
2654  return st_centroid_sig;
2655  }
2656  }
2657 
2658  static class ST_Buffer extends SqlFunction {
2660  super("ST_Buffer",
2661  SqlKind.OTHER_FUNCTION,
2662  null,
2663  null,
2664  OperandTypes.family(signature()),
2665  SqlFunctionCategory.SYSTEM);
2666  }
2667 
2668  @Override
2669  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2670  assert opBinding.getOperandCount() == 2;
2671  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2672  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2673  }
2674 
2675  private static java.util.List<SqlTypeFamily> signature() {
2676  java.util.List<SqlTypeFamily> st_buffer_sig =
2677  new java.util.ArrayList<SqlTypeFamily>();
2678  st_buffer_sig.add(SqlTypeFamily.ANY);
2679  st_buffer_sig.add(SqlTypeFamily.NUMERIC);
2680  return st_buffer_sig;
2681  }
2682  }
2683 
2684  static class ST_ConcaveHull extends SqlFunction {
2686  super("ST_ConcaveHull",
2687  SqlKind.OTHER_FUNCTION,
2688  null,
2689  null,
2690  OperandTypes.family(signature()),
2691  SqlFunctionCategory.SYSTEM);
2692  }
2693 
2694  @Override
2695  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2696  assert opBinding.getOperandCount() == 2;
2697  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2698  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2699  }
2700 
2701  private static java.util.List<SqlTypeFamily> signature() {
2702  java.util.List<SqlTypeFamily> st_concavehull_sig =
2703  new java.util.ArrayList<SqlTypeFamily>();
2704  st_concavehull_sig.add(SqlTypeFamily.ANY);
2705  st_concavehull_sig.add(SqlTypeFamily.NUMERIC);
2706  return st_concavehull_sig;
2707  }
2708  }
2709 
2710  static class ST_ConvexHull extends SqlFunction {
2712  super("ST_ConvexHull",
2713  SqlKind.OTHER_FUNCTION,
2714  null,
2715  null,
2716  OperandTypes.family(signature()),
2717  SqlFunctionCategory.SYSTEM);
2718  }
2719 
2720  @Override
2721  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2722  assert opBinding.getOperandCount() == 1;
2723  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2724  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2725  }
2726 
2727  private static java.util.List<SqlTypeFamily> signature() {
2728  java.util.List<SqlTypeFamily> st_convexhull_sig =
2729  new java.util.ArrayList<SqlTypeFamily>();
2730  st_convexhull_sig.add(SqlTypeFamily.ANY);
2731  return st_convexhull_sig;
2732  }
2733  }
2734 
2735  static class ST_Intersection extends SqlFunction {
2737  super("ST_Intersection",
2738  SqlKind.OTHER_FUNCTION,
2739  null,
2740  null,
2741  OperandTypes.family(signature()),
2742  SqlFunctionCategory.SYSTEM);
2743  }
2744 
2745  @Override
2746  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2747  assert opBinding.getOperandCount() == 2;
2748  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2749  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2750  }
2751 
2752  private static java.util.List<SqlTypeFamily> signature() {
2753  java.util.List<SqlTypeFamily> st_intersection_sig =
2754  new java.util.ArrayList<SqlTypeFamily>();
2755  st_intersection_sig.add(SqlTypeFamily.ANY);
2756  st_intersection_sig.add(SqlTypeFamily.ANY);
2757  return st_intersection_sig;
2758  }
2759  }
2760 
2761  static class ST_Union extends SqlFunction {
2763  super("ST_Union",
2764  SqlKind.OTHER_FUNCTION,
2765  null,
2766  null,
2767  OperandTypes.family(signature()),
2768  SqlFunctionCategory.SYSTEM);
2769  }
2770 
2771  @Override
2772  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2773  assert opBinding.getOperandCount() == 2;
2774  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2775  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2776  }
2777 
2778  private static java.util.List<SqlTypeFamily> signature() {
2779  java.util.List<SqlTypeFamily> st_union_sig =
2780  new java.util.ArrayList<SqlTypeFamily>();
2781  st_union_sig.add(SqlTypeFamily.ANY);
2782  st_union_sig.add(SqlTypeFamily.ANY);
2783  return st_union_sig;
2784  }
2785  }
2786 
2787  static class ST_Difference extends SqlFunction {
2789  super("ST_Difference",
2790  SqlKind.OTHER_FUNCTION,
2791  null,
2792  null,
2793  OperandTypes.family(signature()),
2794  SqlFunctionCategory.SYSTEM);
2795  }
2796 
2797  @Override
2798  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2799  assert opBinding.getOperandCount() == 2;
2800  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2801  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2802  }
2803 
2804  private static java.util.List<SqlTypeFamily> signature() {
2805  java.util.List<SqlTypeFamily> st_difference_sig =
2806  new java.util.ArrayList<SqlTypeFamily>();
2807  st_difference_sig.add(SqlTypeFamily.ANY);
2808  st_difference_sig.add(SqlTypeFamily.ANY);
2809  return st_difference_sig;
2810  }
2811  }
2812 
2813  static class CastToGeography extends SqlFunction {
2815  super("CastToGeography",
2816  SqlKind.OTHER_FUNCTION,
2817  null,
2818  null,
2819  OperandTypes.family(SqlTypeFamily.ANY),
2820  SqlFunctionCategory.SYSTEM);
2821  }
2822 
2823  @Override
2824  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2825  assert opBinding.getOperandCount() == 1;
2826  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2827  return typeFactory.createSqlType(SqlTypeName.INTEGER);
2828  }
2829  }
2830 
2831  static class EncodeText extends SqlFunction {
2833  super("ENCODE_TEXT",
2834  SqlKind.OTHER_FUNCTION,
2835  null,
2836  null,
2837  OperandTypes.family(SqlTypeFamily.STRING),
2838  SqlFunctionCategory.SYSTEM);
2839  }
2840 
2841  @Override
2842  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2843  assert opBinding.getOperandCount() == 1;
2844  return opBinding.getOperandType(0);
2845  }
2846  }
2847 
2848  /* OFFSET_IN_FRAGMENT() */
2849  public static class OffsetInFragment extends SqlFunction {
2850  public OffsetInFragment() {
2851  super("OFFSET_IN_FRAGMENT",
2852  SqlKind.OTHER_FUNCTION,
2853  null,
2854  null,
2855  OperandTypes.NILADIC,
2856  SqlFunctionCategory.SYSTEM);
2857  }
2858 
2859  @Override
2860  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2861  assert opBinding.getOperandCount() == 0;
2862  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2863  return typeFactory.createSqlType(SqlTypeName.BIGINT);
2864  }
2865  }
2866 
2867  static class ApproxCountDistinct extends SqlAggFunction {
2869  super("APPROX_COUNT_DISTINCT",
2870  null,
2871  SqlKind.OTHER_FUNCTION,
2872  null,
2873  null,
2874  OperandTypes.or(OperandTypes.family(SqlTypeFamily.ANY),
2875  OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER)),
2876  SqlFunctionCategory.SYSTEM,
2877  false,
2878  false,
2879  Optionality.FORBIDDEN);
2880  }
2881 
2882  @Override
2883  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2884  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2885  return typeFactory.createSqlType(SqlTypeName.BIGINT);
2886  }
2887  }
2888 
2889  static class ApproxMedian extends SqlAggFunction {
2891  super("APPROX_MEDIAN",
2892  SqlKind.OTHER_FUNCTION,
2893  null,
2894  null,
2895  OperandTypes.family(SqlTypeFamily.NUMERIC),
2896  SqlFunctionCategory.SYSTEM);
2897  }
2898 
2899  @Override
2900  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2901  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2902  return typeFactory.createSqlType(SqlTypeName.DOUBLE);
2903  }
2904  }
2905 
2906  static class ApproxPercentile extends SqlAggFunction {
2908  super("APPROX_PERCENTILE",
2909  SqlKind.OTHER_FUNCTION,
2910  null,
2911  null,
2912  OperandTypes.family(SqlTypeFamily.NUMERIC, SqlTypeFamily.NUMERIC),
2913  SqlFunctionCategory.SYSTEM);
2914  }
2915 
2916  @Override
2917  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2918  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2919  return typeFactory.createSqlType(SqlTypeName.DOUBLE);
2920  }
2921  }
2922 
2923  static class ApproxQuantile extends SqlAggFunction {
2925  super("APPROX_QUANTILE",
2926  SqlKind.OTHER_FUNCTION,
2927  null,
2928  null,
2929  OperandTypes.family(SqlTypeFamily.NUMERIC, SqlTypeFamily.NUMERIC),
2930  SqlFunctionCategory.SYSTEM);
2931  }
2932 
2933  @Override
2934  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2935  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2936  return typeFactory.createSqlType(SqlTypeName.DOUBLE);
2937  }
2938  }
2939 
2940  static class MapDAvg extends SqlAggFunction {
2942  super("AVG",
2943  null,
2944  SqlKind.OTHER_FUNCTION,
2945  null,
2946  null,
2947  OperandTypes.or(OperandTypes.family(SqlTypeFamily.NUMERIC),
2948  OperandTypes.family(SqlTypeFamily.GEO)),
2949  SqlFunctionCategory.SYSTEM);
2950  }
2951 
2952  @Override
2953  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2954  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
2955  return typeFactory.createSqlType(SqlTypeName.DOUBLE);
2956  }
2957  }
2958 
2959  static class Mode extends SqlAggFunction {
2960  Mode() {
2961  super("MODE",
2962  SqlKind.OTHER_FUNCTION,
2963  null,
2964  null,
2965  OperandTypes.ANY,
2966  SqlFunctionCategory.SYSTEM);
2967  }
2968 
2969  @Override
2970  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2971  return opBinding.getOperandType(0);
2972  }
2973  }
2974 
2975  public static class Sample extends SqlAggFunction {
2976  public Sample() {
2977  super("SAMPLE",
2978  null,
2979  SqlKind.OTHER_FUNCTION,
2980  null,
2981  null,
2982  OperandTypes.ANY,
2983  SqlFunctionCategory.SYSTEM,
2984  false,
2985  false,
2986  Optionality.FORBIDDEN);
2987  }
2988 
2989  @Override
2990  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
2991  return opBinding.getOperandType(0);
2992  }
2993  }
2994 
2995  // for backwards compatibility
2996  public static class LastSample extends SqlAggFunction {
2997  public LastSample() {
2998  super("LAST_SAMPLE",
2999  null,
3000  SqlKind.OTHER_FUNCTION,
3001  null,
3002  null,
3003  OperandTypes.ANY,
3004  SqlFunctionCategory.SYSTEM,
3005  false,
3006  false,
3007  Optionality.FORBIDDEN);
3008  }
3009 
3010  @Override
3011  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3012  return opBinding.getOperandType(0);
3013  }
3014  }
3015 
3016  static class CountIf extends SqlAggFunction {
3018  super("COUNT_IF",
3019  null,
3020  SqlKind.OTHER_FUNCTION,
3021  null,
3022  null,
3023  OperandTypes.ANY,
3024  SqlFunctionCategory.SYSTEM,
3025  false,
3026  false,
3027  Optionality.FORBIDDEN);
3028  }
3029 
3030  @Override
3031  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3032  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3033  return typeFactory.createTypeWithNullability(
3034  typeFactory.createSqlType(SqlTypeName.BIGINT), false);
3035  }
3036  }
3037 
3038  static class SumIf extends SqlAggFunction {
3039  SumIf() {
3040  super("SUM_IF",
3041  SqlKind.OTHER_FUNCTION,
3042  null,
3043  null,
3044  OperandTypes.family(SqlTypeFamily.NUMERIC, SqlTypeFamily.BOOLEAN),
3045  SqlFunctionCategory.SYSTEM);
3046  }
3047 
3048  @Override
3049  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3050  return opBinding.getOperandType(0);
3051  }
3052  }
3053 
3054  public static class ConditionalChangeEvent extends SqlAggFunction {
3056  super("CONDITIONAL_CHANGE_EVENT",
3057  null,
3058  SqlKind.OTHER_FUNCTION,
3059  null,
3060  null,
3061  OperandTypes.family(SqlTypeFamily.ANY),
3062  SqlFunctionCategory.SYSTEM,
3063  false,
3064  true,
3065  Optionality.FORBIDDEN);
3066  }
3067 
3068  @Override
3069  public boolean allowsFraming() {
3070  return true;
3071  }
3072 
3073  @Override
3074  public boolean allowsNullTreatment() {
3075  return true;
3076  }
3077 
3078  @Override
3079  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3080  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3081  return typeFactory.createSqlType(SqlTypeName.BIGINT);
3082  }
3083  }
3084 
3085  static class ExtFunction extends SqlFunction {
3086  ExtFunction(final String name, final ExtensionFunction sig) {
3087  super(name,
3088  SqlKind.OTHER_FUNCTION,
3089  null,
3090  null,
3091  OperandTypes.family(sig.toSqlSignature()),
3092  SqlFunctionCategory.USER_DEFINED_FUNCTION);
3093  this.sig = sig;
3094  arg_names = sig.getArgNames();
3095  }
3096 
3097  @Override
3098  public List<String> getParamNames() {
3099  return arg_names;
3100  }
3101 
3102  @Override
3103  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3104  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3105  if (ExtensionFunction.isArrayType(sig.getRet())) {
3106  SqlTypeName valueType =
3107  toSqlTypeName(ExtensionFunction.getValueType(sig.getRet()));
3108  RelDataType subType = typeFactory.createSqlType(valueType, -1);
3109  RelDataType arr = typeFactory.createArrayType(subType, -1);
3110  // should the return type nullable property be true?
3111  return arr;
3112  } else {
3113  SqlTypeName ret = sig.getSqlRet();
3114  return typeFactory.createTypeWithNullability(
3115  typeFactory.createSqlType(ret), true);
3116  }
3117  }
3118 
3119  private final ExtensionFunction sig;
3120  private final List<String> arg_names;
3121  }
3122 
3123  public class ExtTableFunction extends SqlFunction implements SqlTableFunction {
3124  ExtTableFunction(final String name, final ExtensionFunction sig) {
3125  super(name,
3126  SqlKind.OTHER_FUNCTION,
3127  ReturnTypes.CURSOR,
3128  null,
3130  SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION);
3131  arg_types = sig.getArgs();
3132  outs = sig.getOuts();
3133  out_names = sig.getOutNames();
3134  arg_names = sig.getArgNames();
3135  // pretty_arg_names will be same as arg_names, except with
3136  // arg names for cursors stripped of array elements, i.e
3137  // my_cursor_input[x, y, z] => my_cursor_input
3138  pretty_arg_names = sig.getPrettyArgNames();
3139  options = sig.getOptions();
3140  cursor_field_types = sig.getCursorFieldTypes();
3141  default_values = sig.getDefaultValues();
3142  }
3143 
3144  // The following method allows for parameter annotation
3145  // i.e. my_param => 3.
3146  // Note this method is deprecated, and it appears that
3147  // getParameters() is the correct method to use, but
3148  // need to troubleshoot why it's not being called
3149  @Override
3150  public List<String> getParamNames() {
3151  return pretty_arg_names;
3152  }
3153 
3154  // Per the above, this appears to be the non-deprecated way
3155  // to allow for parameter annotation, and it also allows
3156  // for specifying optionality.
3157  // However it currently is not being picked up/called,
3158  // so need to troubleshot. Leaving in for now as scaffolding
3159  // for the correct approach forward.
3160 
3161  // Note that OperandTypeInference seems another route
3162  // to implementing optionality.
3163 
3164  public List<FunctionParameter> getParameters() {
3165  final Boolean has_names = this.pretty_arg_names != null
3166  && this.pretty_arg_names.size() == this.arg_types.size();
3167  final List<FunctionParameter> parameters = new java.util.ArrayList<>();
3168  for (int i = 0; i < this.arg_types.size(); i++) {
3169  final int arg_idx = i;
3170  parameters.add(new FunctionParameter() {
3171  public int getOrdinal() {
3172  return arg_idx;
3173  }
3174 
3175  public String getName() {
3176  if (has_names) {
3177  return pretty_arg_names.get(arg_idx);
3178  }
3179  return "arg" + arg_idx;
3180  }
3181 
3182  public RelDataType getType(RelDataTypeFactory typeFactory) {
3183  SqlTypeFamily type = toSqlTypeName(arg_types.get(arg_idx)).getFamily();
3184  return type.getDefaultConcreteType(typeFactory);
3185  }
3186 
3187  public boolean isOptional() {
3188  return false;
3189  }
3190  });
3191  }
3192  return parameters;
3193  }
3194 
3195  @Override
3196  public SqlReturnTypeInference getRowTypeInference() {
3197  return opBinding -> {
3198  RelDataTypeFactory fact = opBinding.getTypeFactory();
3199  FieldInfoBuilder ret = fact.builder();
3200  for (int out_idx = 0; out_idx < outs.size(); ++out_idx) {
3201  RelDataType type;
3202  if (toSqlTypeName(outs.get(out_idx)) == SqlTypeName.ARRAY) {
3203  ExtArgumentType extSubType = getValueType(outs.get(out_idx));
3204  if (ExtensionFunction.isColumnArrayType(outs.get(out_idx))) {
3205  extSubType = getValueType(extSubType);
3206  }
3207  RelDataType subtype = fact.createSqlType(toSqlTypeName(extSubType));
3208  type = fact.createArrayType(subtype, -1);
3209  } else {
3210  type = fact.createSqlType(toSqlTypeName(outs.get(out_idx)));
3211  }
3212  ret = ret.add(out_names.get(out_idx), type);
3213  ret = ret.nullable(true);
3214  }
3215  return ret.build();
3216  };
3217  }
3218 
3219  private void debugPrint(String msg, Boolean debugMode) {
3220  if (debugMode) {
3221  System.out.println(msg);
3222  }
3223  }
3224 
3225  public Set<RelColumnMapping> getColumnMappings() {
3226  final Boolean debugMode = false;
3227  Set<RelColumnMapping> s = new HashSet<RelColumnMapping>();
3228  debugPrint("getNameAsId() -> " + getNameAsId() + ", arg_names=" + arg_names
3229  + ", out_names=" + out_names,
3230  debugMode);
3231  if (Integer.valueOf(options.getOrDefault("filter_table_function_transpose", "0"))
3232  == 1) {
3233  debugPrint("getNameAsId() -> " + getNameAsId(), debugMode);
3234  int rel_idx = -1;
3235  for (int arg_idx = 0; arg_idx < arg_names.size(); ++arg_idx) {
3236  String arg_name = arg_names.get(arg_idx);
3237  String[] fields;
3238  int start = arg_name.indexOf("[");
3239  if (start != -1) {
3240  rel_idx += 1;
3241  int end = arg_name.lastIndexOf("]");
3242  fields = arg_name.substring(start + 1, end)
3243  .replaceAll("\\s+", "")
3244  .split(",", 0);
3245  } else {
3246  fields = new String[] {arg_name};
3247  }
3248  debugPrint("fields=" + Arrays.toString(fields), debugMode);
3249  for (int field_idx = 0; field_idx < fields.length; ++field_idx) {
3250  int out_idx = out_names.indexOf(fields[field_idx]);
3251  if (out_idx >= 0) {
3252  s.add(new RelColumnMapping(out_idx, rel_idx, field_idx, false));
3253  debugPrint("out_idx, arg_idx/rel_idx, field_idx=" + out_idx + ", " + arg_idx
3254  + "/" + rel_idx + ", " + field_idx,
3255  debugMode);
3256  }
3257  }
3258  }
3259  }
3260  return s;
3261  }
3262 
3263  // Returns the table function's signature, with extended operand
3264  // type information, including CURSOR field types and operand
3265  // names.
3266 
3267  // E.g. for the following UDTF:
3268  // my_udtf(Column<int64_t> input_col) -> Column<int64_t>
3269  // it'll build the signature:
3270  // 'my_udtf(input_col => <CURSOR>[BIGINT])'
3271 
3272  public String getExtendedSignature() {
3273  StringBuilder ret = new StringBuilder();
3274  ret.append("'");
3275  ret.append(this.getName());
3276  ret.append("(");
3277 
3278  for (int i = 0; i < this.arg_types.size(); i++) {
3279  if (i > 0) {
3280  ret.append(", ");
3281  }
3282 
3283  ExtArgumentType type = arg_types.get(i);
3284  String paramName = arg_names.get(i);
3285  ret.append(paramName).append(" => ");
3286 
3287  final String t = type.toString().toUpperCase(Locale.ROOT);
3288  ret.append("<").append(t);
3289  if (type == ExtArgumentType.Cursor) {
3290  List<ExtensionFunction.ExtArgumentType> field_types =
3291  cursor_field_types.get(paramName);
3292  ret.append("[");
3293  for (int j = 0; j < field_types.size(); j++) {
3294  if (j > 0) {
3295  ret.append(",");
3296  }
3297  ExtArgumentType field_type = field_types.get(j);
3298  ret.append(toSqlTypeName(field_type));
3299  if (isColumnListType(field_type)) {
3300  ExtArgumentType subtype = getValueType(field_type);
3301  ret.append("[");
3302  ret.append(toSqlTypeName(subtype));
3303  ret.append("]");
3304  } else if (isColumnArrayType(field_type) || isArrayType(field_type)) {
3305  ExtArgumentType subtype = getValueType(getValueType(field_type));
3306  ret.append("[");
3307  ret.append(toSqlTypeName(subtype));
3308  ret.append("]");
3309  }
3310  }
3311  ret.append("]");
3312  }
3313  ret.append(">");
3314  }
3315  ret.append(")'");
3316 
3317  return ret.toString();
3318  }
3319 
3320  // This returns the original arg names, with CURSOR field names included.
3321  // Is used to map arguments to their input annotations.
3322  public List<String> getExtendedParamNames() {
3323  return this.arg_names;
3324  }
3325 
3326  // Required to store ExtTableFunctions in Collections
3327  @Override
3328  public int hashCode() {
3329  return this.getExtendedSignature().hashCode();
3330  }
3331 
3332  // Required to store ExtTableFunctions in Collections
3333  // We disambiguate ExtTableFunctions by their names and input arg
3334  // types, including CURSOR field types.
3335  @Override
3336  public boolean equals(final Object obj) {
3337  if (obj == null) {
3338  return false;
3339  }
3340 
3341  if (getClass() != obj.getClass()) {
3342  return false;
3343  }
3344 
3345  if (this == obj) {
3346  return true;
3347  }
3348 
3349  final ExtTableFunction other = (ExtTableFunction) obj;
3350  if (!this.getName().equals(other.getName())) {
3351  return false;
3352  }
3353  if (arg_types.size() != other.arg_types.size()) {
3354  return false;
3355  }
3356 
3357  for (int i = 0; i < arg_types.size(); i++) {
3358  if (arg_types.get(i) != other.arg_types.get(i)) {
3359  return false;
3360  }
3361  if (arg_types.get(i) == ExtArgumentType.Cursor) {
3362  String paramName = this.arg_names.get(i);
3363  String otherParamName = other.getExtendedParamNames().get(i);
3364  if (!paramName.equals(otherParamName)) {
3365  return false;
3366  }
3367 
3368  List<ExtArgumentType> field_types = this.getCursorFieldTypes().get(paramName);
3369  List<ExtArgumentType> other_field_types =
3370  other.getCursorFieldTypes().get(paramName);
3371  if (field_types.size() != other_field_types.size()) {
3372  return false;
3373  }
3374  for (int j = 0; j < field_types.size(); j++) {
3375  if (field_types.get(j) != other_field_types.get(j)) {
3376  return false;
3377  }
3378  }
3379  }
3380  }
3381  return true;
3382  }
3383 
3384  @Override
3385  public String toString() {
3386  return getExtendedSignature();
3387  }
3388 
3389  public Map<String, List<ExtArgumentType>> getCursorFieldTypes() {
3390  return cursor_field_types;
3391  }
3392 
3393  public List<ExtArgumentType> getArgTypes() {
3394  return arg_types;
3395  }
3396 
3397  Map<String, Comparable<?>> getDefaultValues() {
3398  return default_values;
3399  }
3400 
3401  public boolean supportsDefaultArguments() {
3402  return (default_values.size() > 0);
3403  }
3404 
3405  /* Returns whether the i-th argument is optional. That is, whether it has an
3406  * associated default value.
3407  */
3408  public boolean isArgumentOptional(int i) {
3409  String paramName = getParamNames().get(i);
3410  return getDefaultValues().get(paramName) != null;
3411  }
3412 
3414  return getDefaultValues().size();
3415  }
3416 
3417  /* Rewrites a call to the table function containing DEFAULT arguments, replacing the
3418  * DEFAULT actual parameter literals by the default value for that parameter specified
3419  * in the table function's signature.
3420  *
3421  * e.g. signature: my_udtf(Column<int> col, int scalar | default=10)
3422  *
3423  * call 'select * from table(my_udtf(cursor(select int_col from table), DEFAULT))' ->
3424  * 'select * from table(my_udtf(cursor(select int_col from table), 10))'
3425  *
3426  * for calls with named arguments, the explicit DEFAULTs can be omitted:
3427  * call 'select * from table(my_udtf(inp0 => cursor(select int_col from table)))' ->
3428  * 'select * from table(my_udtf(cursor(select int_col from table), 10))
3429  */
3430  public SqlCall rewriteCallWithDefaultArguments(SqlCall permutedCall) {
3431  for (Ord<SqlNode> operand : Ord.zip(permutedCall.getOperandList())) {
3432  if (operand.e.getClass() == SqlBasicCall.class) {
3433  SqlBasicCall operandAsCall = (SqlBasicCall) operand.e;
3434  if (operandAsCall.getOperator().getName() == "DEFAULT") {
3435  ExtTableFunction tf = (ExtTableFunction) permutedCall.getOperator();
3436  String paramName = tf.getExtendedParamNames().get(operand.i);
3437  Comparable<?> defaultVal = tf.getDefaultValues().get(paramName);
3438  SqlLiteral newOperand = createLiteralForDefaultValue(
3439  defaultVal, operand.e.getParserPosition());
3440  permutedCall.setOperand(operand.i, newOperand);
3441  }
3442  }
3443  }
3444  return permutedCall;
3445  }
3446 
3447  SqlLiteral createLiteralForDefaultValue(Comparable<?> value, SqlParserPos pos) {
3448  if (value instanceof Integer || value instanceof Long || value instanceof Float
3449  || value instanceof Double) {
3450  return SqlLiteral.createExactNumeric(value.toString(), pos);
3451  } else if (value instanceof Boolean) {
3452  Boolean asBool = (Boolean) value;
3453  return SqlLiteral.createBoolean(asBool.booleanValue(), pos);
3454  } else if (value instanceof String) {
3455  return SqlLiteral.createCharString(value.toString(), pos);
3456  } else {
3457  return null;
3458  }
3459  }
3460 
3461  @Override
3462  public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
3463  // We need to override this because the default Calcite implementation adds logic to
3464  // handle default values before deferring typechecking to the operator's own
3465  // SqlOperandTypeChecker. Since we want to handle default values differently for
3466  // UDTFs, this method bypasses that logic and simply calls the type checker
3467  // directly.
3468  return getOperandTypeChecker().checkOperandTypes(callBinding, throwOnFailure);
3469  }
3470 
3471  private final List<ExtArgumentType> arg_types;
3472  private final List<ExtArgumentType> outs;
3473  private final List<String> arg_names;
3474  private final List<String> pretty_arg_names;
3475  private final List<String> out_names;
3476  private final Map<String, String> options;
3477  private final Map<String, List<ExtArgumentType>> cursor_field_types;
3478  private final Map<String, Comparable<?>> default_values;
3479  }
3480 
3481  //
3482  // Temporary internal accessors for passing poly data into UDTFs
3483  //
3484 
3485  static class HeavyDB_Geo_PolyBoundsPtr extends SqlFunction {
3487  super("HeavyDB_Geo_PolyBoundsPtr",
3488  SqlKind.OTHER_FUNCTION,
3489  null,
3490  null,
3491  OperandTypes.family(SqlTypeFamily.ANY),
3492  SqlFunctionCategory.SYSTEM);
3493  }
3494 
3495  @Override
3496  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3497  assert opBinding.getOperandCount() == 1;
3498  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3499  return typeFactory.createSqlType(SqlTypeName.BIGINT);
3500  }
3501  }
3502 
3503  static class convert_meters_to_pixel_width extends SqlFunction {
3505  super("convert_meters_to_pixel_width",
3506  SqlKind.OTHER_FUNCTION,
3507  null,
3508  null,
3509  OperandTypes.family(SqlTypeFamily.NUMERIC,
3510  SqlTypeFamily.ANY,
3511  SqlTypeFamily.NUMERIC,
3512  SqlTypeFamily.NUMERIC,
3513  SqlTypeFamily.NUMERIC,
3514  SqlTypeFamily.NUMERIC),
3515  SqlFunctionCategory.SYSTEM);
3516  }
3517 
3518  @Override
3519  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3520  assert opBinding.getOperandCount() == 6;
3521  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3522  return typeFactory.createSqlType(SqlTypeName.DOUBLE);
3523  }
3524  }
3525 
3526  static class convert_meters_to_pixel_height extends SqlFunction {
3528  super("convert_meters_to_pixel_height",
3529  SqlKind.OTHER_FUNCTION,
3530  null,
3531  null,
3532  OperandTypes.family(SqlTypeFamily.NUMERIC,
3533  SqlTypeFamily.ANY,
3534  SqlTypeFamily.NUMERIC,
3535  SqlTypeFamily.NUMERIC,
3536  SqlTypeFamily.NUMERIC,
3537  SqlTypeFamily.NUMERIC),
3538  SqlFunctionCategory.SYSTEM);
3539  }
3540 
3541  @Override
3542  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3543  assert opBinding.getOperandCount() == 6;
3544  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3545  return typeFactory.createSqlType(SqlTypeName.DOUBLE);
3546  }
3547  }
3548 
3549  static class is_point_in_view extends SqlFunction {
3551  super("is_point_in_view",
3552  SqlKind.OTHER_FUNCTION,
3553  null,
3554  null,
3555  OperandTypes.family(SqlTypeFamily.ANY,
3556  SqlTypeFamily.NUMERIC,
3557  SqlTypeFamily.NUMERIC,
3558  SqlTypeFamily.NUMERIC,
3559  SqlTypeFamily.NUMERIC),
3560  SqlFunctionCategory.SYSTEM);
3561  }
3562 
3563  @Override
3564  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3565  assert opBinding.getOperandCount() == 5;
3566  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3567  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
3568  }
3569  }
3570 
3571  static class is_point_size_in_view extends SqlFunction {
3573  super("is_point_size_in_view",
3574  SqlKind.OTHER_FUNCTION,
3575  null,
3576  null,
3577  OperandTypes.family(SqlTypeFamily.ANY,
3578  SqlTypeFamily.NUMERIC,
3579  SqlTypeFamily.NUMERIC,
3580  SqlTypeFamily.NUMERIC,
3581  SqlTypeFamily.NUMERIC,
3582  SqlTypeFamily.NUMERIC),
3583  SqlFunctionCategory.SYSTEM);
3584  }
3585 
3586  @Override
3587  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3588  assert opBinding.getOperandCount() == 6;
3589  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3590  return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
3591  }
3592  }
3593 
3594  public static class usTimestamp extends SqlFunction {
3595  public usTimestamp() {
3596  super("usTIMESTAMP",
3597  SqlKind.OTHER_FUNCTION,
3598  null,
3599  null,
3600  OperandTypes.STRING,
3601  SqlFunctionCategory.SYSTEM);
3602  }
3603 
3604  @Override
3605  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3606  assert opBinding.getOperandCount() == 1;
3607  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3608  return typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 6);
3609  }
3610  }
3611 
3612  public static class nsTimestamp extends SqlFunction {
3613  public nsTimestamp() {
3614  super("nsTIMESTAMP",
3615  SqlKind.OTHER_FUNCTION,
3616  null,
3617  null,
3618  OperandTypes.STRING,
3619  SqlFunctionCategory.SYSTEM);
3620  }
3621 
3622  @Override
3623  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
3624  assert opBinding.getOperandCount() == 1;
3625  final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
3626  return typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 9);
3627  }
3628  }
3629 
3630  public class ForwardFill extends SqlAggFunction {
3631  public ForwardFill() {
3632  super("FORWARD_FILL",
3633  null,
3634  SqlKind.WINDOW,
3635  ReturnTypes.ARG0,
3636  null,
3637  OperandTypes.family(SqlTypeFamily.ANY),
3638  SqlFunctionCategory.SYSTEM,
3639  false,
3640  true,
3641  Optionality.FORBIDDEN);
3642  }
3643 
3644  @Override
3645  public boolean allowsFraming() {
3646  return false;
3647  }
3648  }
3649 
3650  public class BackwardFill extends SqlAggFunction {
3651  public BackwardFill() {
3652  super("BACKWARD_FILL",
3653  null,
3654  SqlKind.WINDOW,
3655  ReturnTypes.ARG0,
3656  null,
3657  OperandTypes.family(SqlTypeFamily.ANY),
3658  SqlFunctionCategory.SYSTEM,
3659  false,
3660  true,
3661  Optionality.FORBIDDEN);
3662  }
3663 
3664  @Override
3665  public boolean allowsFraming() {
3666  return false;
3667  }
3668  }
3669 }
3670 
3671 // End HeavyDBSqlOperatorTable.java
EXTENSION_NOINLINE double convert_meters_to_pixel_width(const double meters, int8_t *p, const int64_t psize, const int32_t ic, const int32_t isr, const int32_t osr, const double min_lon, const double max_lon, const int32_t img_width, const double min_width)
EXTENSION_INLINE int64_t HeavyDB_Geo_PolyBoundsPtr(double *bounds, int64_t size)
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
RelDataType inferReturnType(SqlOperatorBinding opBinding)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
ExtTableFunction(final String name, final ExtensionFunction sig)
EXTENSION_NOINLINE double ST_XMax(int8_t *coords, int64_t size, int32_t ic, int32_t isr, int32_t osr)
boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
ExInst< SqlValidatorException > illegalArrayLengthCall(String query)
EXTENSION_NOINLINE bool is_point_size_in_view(int8_t *p, const int64_t psize, const int32_t ic, const double meters, const double min_lon, const double max_lon, const double min_lat, const double max_lat)
EXTENSION_NOINLINE double ST_YMax(int8_t *coords, int64_t size, int32_t ic, int32_t isr, int32_t osr)
SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,@Nullable SqlNode...operands)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
EXTENSION_NOINLINE double ST_XMin(int8_t *coords, int64_t size, int32_t ic, int32_t isr, int32_t osr)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
EXTENSION_NOINLINE double convert_meters_to_pixel_height(const double meters, int8_t *p, const int64_t psize, const int32_t ic, const int32_t isr, const int32_t osr, const double min_lat, const double max_lat, const int32_t img_height, const double min_height)
tuple STRING
Definition: dtypes.py:31
boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
static java.util.List< SqlTypeFamily > getSignatureFamilies()
RelDataType inferReturnType(SqlOperatorBinding opBinding)
RelDataType getComponentType(RelDataTypeFactory typeFactory, List< RelDataType > argTypes)
EXTENSION_NOINLINE double ST_YMin(int8_t *coords, int64_t size, int32_t ic, int32_t isr, int32_t osr)
SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,@Nullable SqlNode...operands)
static java.util.List< SqlTypeFamily > getSignatureFamilies()
RelDataType inferReturnType(SqlOperatorBinding opBinding)
static boolean isColumnArrayType(final ExtArgumentType type)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
void addUDF(final Map< String, ExtensionFunction > extSigs)
void validateCall(SqlCall call, SqlValidator validator, SqlValidatorScope scope, SqlValidatorScope operandScope)
EXTENSION_NOINLINE bool is_point_in_view(int8_t *p, const int64_t psize, const int32_t ic, const double min_lon, const double max_lon, const double min_lat, const double max_lat)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
ExtFunction(final String name, final ExtensionFunction sig)
SqlLiteral createLiteralForDefaultValue(Comparable<?> value, SqlParserPos pos)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
static java.util.List< SqlTypeFamily > getSignatureFamilies()
RelDataType inferReturnType(SqlOperatorBinding opBinding)
static java.util.List< SqlTypeFamily > getSignatureFamilies()
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec)
static boolean isArrayType(final ExtArgumentType type)
SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,@Nullable SqlNode...operands)
SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,@Nullable SqlNode...operands)
EXTENSION_NOINLINE double Truncate(const double x, const int32_t y)
static java.util.List< SqlTypeFamily > getSignatureFamilies()
SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,@Nullable SqlNode...operands)
boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,@Nullable SqlNode...operands)
string name
Definition: setup.in.py:72
boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
static final SqlArrayValueConstructorAllowingEmpty ARRAY_VALUE_CONSTRUCTOR
RelDataType inferReturnType(SqlOperatorBinding opBinding)
static ExtArgumentType getValueType(final ExtArgumentType type)
RelDataType inferReturnType(SqlOperatorBinding opBinding)
void lookupOperatorOverloads(SqlIdentifier opName, SqlFunctionCategory category, SqlSyntax syntax, List< SqlOperator > operatorList, SqlNameMatcher nameMatcher)
RelDataType inferReturnType(SqlOperatorBinding opBinding)