OmniSciDB  085a039ca4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CalciteServerHandler.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 package com.mapd.parser.server;
17 
18 import static com.mapd.calcite.parser.HeavyDBParser.CURRENT_PARSER;
19 
24 
28 import org.apache.calcite.runtime.CalciteContextException;
29 import org.apache.calcite.sql.SqlNode;
30 import org.apache.calcite.sql.parser.SqlParseException;
31 import org.apache.calcite.sql.validate.SqlMoniker;
32 import org.apache.calcite.sql.validate.SqlMonikerType;
33 import org.apache.calcite.tools.RelConversionException;
34 import org.apache.calcite.tools.ValidationException;
35 import org.apache.calcite.util.Pair;
36 import org.apache.commons.pool.PoolableObjectFactory;
37 import org.apache.commons.pool.impl.GenericObjectPool;
38 import org.apache.thrift.TException;
39 import org.apache.thrift.server.TServer;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42 
43 import java.io.IOException;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 
49 import ai.heavy.thrift.calciteserver.CalciteServer;
50 import ai.heavy.thrift.calciteserver.InvalidParseRequest;
51 import ai.heavy.thrift.calciteserver.TAccessedQueryObjects;
52 import ai.heavy.thrift.calciteserver.TCompletionHint;
53 import ai.heavy.thrift.calciteserver.TCompletionHintType;
54 import ai.heavy.thrift.calciteserver.TExtArgumentType;
55 import ai.heavy.thrift.calciteserver.TFilterPushDownInfo;
56 import ai.heavy.thrift.calciteserver.TOptimizationOption;
57 import ai.heavy.thrift.calciteserver.TPlanResult;
58 import ai.heavy.thrift.calciteserver.TQueryParsingOption;
59 import ai.heavy.thrift.calciteserver.TRestriction;
60 import ai.heavy.thrift.calciteserver.TUserDefinedFunction;
61 import ai.heavy.thrift.calciteserver.TUserDefinedTableFunction;
62 
67 public class CalciteServerHandler implements CalciteServer.Iface {
68  final static Logger HEAVYDBLOGGER = LoggerFactory.getLogger(CalciteServerHandler.class);
69  private TServer server;
70 
71  private final int dbPort;
72 
73  private volatile long callCount;
74 
75  private final GenericObjectPool parserPool;
76 
78 
79  private final String extSigsJson;
80 
81  private final String udfSigsJson;
82 
83  private String udfRTSigsJson = "";
84  Map<String, ExtensionFunction> udfRTSigs = null;
85 
86  Map<String, ExtensionFunction> udtfSigs = null;
87 
89  private Map<String, ExtensionFunction> extSigs = null;
90  private String dataDir;
91 
92  // TODO MAT we need to merge this into common code base for these functions with
93  // CalciteDirect since we are not deprecating this stuff yet
95  String dataDir,
96  String extensionFunctionsAstFile,
98  String udfAstFile) {
99  this.dbPort = dbPort;
100  this.dataDir = dataDir;
101 
102  Map<String, ExtensionFunction> udfSigs = null;
103 
104  try {
105  extSigs = ExtensionFunctionSignatureParser.parse(extensionFunctionsAstFile);
106  } catch (IOException ex) {
107  HEAVYDBLOGGER.error(
108  "Could not load extension function signatures: " + ex.getMessage(), ex);
109  }
110  extSigsJson = ExtensionFunctionSignatureParser.signaturesToJson(extSigs);
111 
112  try {
113  if (!udfAstFile.isEmpty()) {
114  udfSigs = ExtensionFunctionSignatureParser.parseUdfAst(udfAstFile);
115  }
116  } catch (IOException ex) {
117  HEAVYDBLOGGER.error(
118  "Could not load udf function signatures: " + ex.getMessage(), ex);
119  }
120  udfSigsJson = ExtensionFunctionSignatureParser.signaturesToJson(udfSigs);
121 
122  // Put all the udf functions signatures in extSigs so Calcite has a view of
123  // extension functions and udf functions
124  if (!udfAstFile.isEmpty()) {
125  extSigs.putAll(udfSigs);
126  }
127 
128  calciteParserFactory = new CalciteParserFactory(dataDir, extSigs, dbPort, skT);
129 
130  // GenericObjectPool::setFactory is deprecated
131  this.parserPool = new GenericObjectPool(calciteParserFactory);
132  }
133 
134  @Override
135  public void ping() throws TException {
136  HEAVYDBLOGGER.debug("Ping hit");
137  }
138 
139  @Override
140  public TPlanResult process(String user,
141  String session,
142  String catalog,
143  String queryText,
144  TQueryParsingOption queryParsingOption,
145  TOptimizationOption optimizationOption,
146  List<TRestriction> trestrictions) throws InvalidParseRequest, TException {
147  long timer = System.currentTimeMillis();
148  callCount++;
149 
151  try {
152  parser = (HeavyDBParser) parserPool.borrowObject();
153  parser.clearMemo();
154  } catch (Exception ex) {
155  String msg = "Could not get Parse Item from pool: " + ex.getMessage();
156  HEAVYDBLOGGER.error(msg, ex);
157  throw new InvalidParseRequest(-1, msg);
158  }
159  List<Restriction> rests = null;
160  if (trestrictions != null && !trestrictions.isEmpty()) {
161  rests = new ArrayList<>();
162  for (TRestriction trestriction : trestrictions) {
163  Restriction rest = null;
164  rest = new Restriction(trestriction.database,
165  trestriction.table,
166  trestriction.column,
167  trestriction.values);
168  rests.add(rest);
169  }
170  }
171  HeavyDBUser dbUser = new HeavyDBUser(user, session, catalog, dbPort, rests);
172  HEAVYDBLOGGER.debug("process was called User: " + user + " Catalog: " + catalog
173  + " sql: " + queryText);
174  parser.setUser(dbUser);
175  CURRENT_PARSER.set(parser);
176 
177  // need to trim the sql string as it seems it is not trimed prior to here
178  boolean isRAQuery = false;
179 
180  if (queryText.startsWith("execute calcite")) {
181  queryText = queryText.replaceFirst("execute calcite", "");
182  isRAQuery = true;
183  }
184 
185  queryText = queryText.trim();
186  // remove last charcter if it is a ;
187  if (queryText.length() > 0 && queryText.charAt(queryText.length() - 1) == ';') {
188  queryText = queryText.substring(0, queryText.length() - 1);
189  }
190  String jsonResult;
191  SqlIdentifierCapturer capturer;
192  TAccessedQueryObjects primaryAccessedObjects = new TAccessedQueryObjects();
193  TAccessedQueryObjects resolvedAccessedObjects = new TAccessedQueryObjects();
194  try {
195  final List<HeavyDBParserOptions.FilterPushDownInfo> filterPushDownInfo =
196  new ArrayList<>();
197  for (final TFilterPushDownInfo req : optimizationOption.filter_push_down_info) {
198  filterPushDownInfo.add(new HeavyDBParserOptions.FilterPushDownInfo(
199  req.input_prev, req.input_start, req.input_next));
200  }
201  HeavyDBParserOptions parserOptions = new HeavyDBParserOptions(filterPushDownInfo,
202  queryParsingOption.legacy_syntax,
203  queryParsingOption.is_explain,
204  optimizationOption.is_view_optimize,
205  optimizationOption.enable_watchdog);
206 
207  if (!isRAQuery) {
208  Pair<String, SqlIdentifierCapturer> res;
209  SqlNode node;
210 
211  res = parser.process(queryText, parserOptions);
212  jsonResult = res.left;
213  capturer = res.right;
214 
215  primaryAccessedObjects.tables_selected_from = new ArrayList<>(capturer.selects);
216  primaryAccessedObjects.tables_inserted_into = new ArrayList<>(capturer.inserts);
217  primaryAccessedObjects.tables_updated_in = new ArrayList<>(capturer.updates);
218  primaryAccessedObjects.tables_deleted_from = new ArrayList<>(capturer.deletes);
219 
220  // also resolve all the views in the select part
221  // resolution of the other parts is not
222  // necessary as these cannot be views
223  resolvedAccessedObjects.tables_selected_from =
224  new ArrayList<>(parser.resolveSelectIdentifiers(capturer));
225  resolvedAccessedObjects.tables_inserted_into = new ArrayList<>(capturer.inserts);
226  resolvedAccessedObjects.tables_updated_in = new ArrayList<>(capturer.updates);
227  resolvedAccessedObjects.tables_deleted_from = new ArrayList<>(capturer.deletes);
228 
229  } else {
230  jsonResult = parser.optimizeRAQuery(queryText, parserOptions);
231  }
232  } catch (SqlParseException ex) {
233  String msg = "SQL Error: " + ex.getMessage();
234  HEAVYDBLOGGER.error(msg);
235  throw new InvalidParseRequest(-2, msg);
236  } catch (org.apache.calcite.tools.ValidationException ex) {
237  String msg = "SQL Error: " + ex.getMessage();
238  if (ex.getCause() != null
239  && (ex.getCause().getClass() == CalciteContextException.class)) {
240  msg = "SQL Error: " + ex.getCause().getMessage();
241  }
242  HEAVYDBLOGGER.error(msg);
243  throw new InvalidParseRequest(-3, msg);
244  } catch (CalciteContextException ex) {
245  String msg = ex.getMessage();
246  HEAVYDBLOGGER.error(msg);
247  throw new InvalidParseRequest(-6, msg);
248  } catch (RelConversionException ex) {
249  String msg = "Failed to generate relational algebra for query " + ex.getMessage();
250  HEAVYDBLOGGER.error(msg, ex);
251  throw new InvalidParseRequest(-5, msg);
252  } catch (Throwable ex) {
253  HEAVYDBLOGGER.error(ex.getClass().toString());
254  String msg = ex.getMessage();
255  HEAVYDBLOGGER.error(msg, ex);
256  throw new InvalidParseRequest(-4, msg);
257  } finally {
258  CURRENT_PARSER.set(null);
259  try {
260  // put parser object back in pool for others to use
261  parserPool.returnObject(parser);
262  } catch (Exception ex) {
263  String msg = "Could not return parse object: " + ex.getMessage();
264  HEAVYDBLOGGER.error(msg, ex);
265  throw new InvalidParseRequest(-7, msg);
266  }
267  }
268 
269  TPlanResult result = new TPlanResult();
270  result.primary_accessed_objects = primaryAccessedObjects;
271  result.resolved_accessed_objects = resolvedAccessedObjects;
272  result.plan_result = jsonResult;
273  result.execution_time_ms = System.currentTimeMillis() - timer;
274 
275  return result;
276  }
277 
278  @Override
279  public void shutdown() throws TException {
280  // received request to shutdown
281  HEAVYDBLOGGER.debug("Shutdown calcite java server");
282  server.stop();
283  }
284 
285  @Override
287  return this.extSigsJson;
288  }
289 
290  @Override
292  return this.udfSigsJson;
293  }
294 
295  @Override
297  return this.udfRTSigsJson;
298  }
299 
300  void setServer(TServer s) {
301  server = s;
302  }
303 
304  @Override
305  public void updateMetadata(String catalog, String table) throws TException {
306  HEAVYDBLOGGER.debug(
307  "Received invalidation from server for " + catalog + " : " + table);
308  long timer = System.currentTimeMillis();
309  callCount++;
311  try {
312  parser = (HeavyDBParser) parserPool.borrowObject();
313  } catch (Exception ex) {
314  String msg = "Could not get Parse Item from pool: " + ex.getMessage();
315  HEAVYDBLOGGER.error(msg, ex);
316  return;
317  }
318  CURRENT_PARSER.set(parser);
319  try {
320  parser.updateMetaData(catalog, table);
321  } finally {
322  CURRENT_PARSER.set(null);
323  try {
324  // put parser object back in pool for others to use
325  HEAVYDBLOGGER.debug("Returning object to pool");
326  parserPool.returnObject(parser);
327  } catch (Exception ex) {
328  String msg = "Could not return parse object: " + ex.getMessage();
329  HEAVYDBLOGGER.error(msg, ex);
330  }
331  }
332  }
333 
334  @Override
335  public List<TCompletionHint> getCompletionHints(String user,
336  String session,
337  String catalog,
338  List<String> visible_tables,
339  String sql,
340  int cursor) throws TException {
341  callCount++;
343  try {
344  parser = (HeavyDBParser) parserPool.borrowObject();
345  } catch (Exception ex) {
346  String msg = "Could not get Parse Item from pool: " + ex.getMessage();
347  HEAVYDBLOGGER.error(msg, ex);
348  throw new TException(msg);
349  }
350  HeavyDBUser dbUser = new HeavyDBUser(user, session, catalog, dbPort, null);
351  HEAVYDBLOGGER.debug("getCompletionHints was called User: " + user
352  + " Catalog: " + catalog + " sql: " + sql);
353  parser.setUser(dbUser);
354  CURRENT_PARSER.set(parser);
355 
356  HeavyDBPlanner.CompletionResult completion_result;
357  try {
358  completion_result = parser.getCompletionHints(sql, cursor, visible_tables);
359  } catch (Exception ex) {
360  String msg = "Could not retrieve completion hints: " + ex.getMessage();
361  HEAVYDBLOGGER.error(msg, ex);
362  return new ArrayList<>();
363  } finally {
364  CURRENT_PARSER.set(null);
365  try {
366  // put parser object back in pool for others to use
367  parserPool.returnObject(parser);
368  } catch (Exception ex) {
369  String msg = "Could not return parse object: " + ex.getMessage();
370  HEAVYDBLOGGER.error(msg, ex);
371  throw new InvalidParseRequest(-4, msg);
372  }
373  }
374  List<TCompletionHint> result = new ArrayList<>();
375  for (final SqlMoniker hint : completion_result.hints) {
376  result.add(new TCompletionHint(hintTypeToThrift(hint.getType()),
377  hint.getFullyQualifiedNames(),
378  completion_result.replaced));
379  }
380  return result;
381  }
382 
383  @Override
384  public void setRuntimeExtensionFunctions(List<TUserDefinedFunction> udfs,
385  List<TUserDefinedTableFunction> udtfs,
386  boolean isruntime) {
387  if (isruntime) {
388  // Clean up previously defined Runtime UDFs
389  if (udfRTSigs != null) {
390  for (String name : udfRTSigs.keySet()) extSigs.remove(name);
391  udfRTSigsJson = "";
392  udfRTSigs.clear();
393  } else {
394  udfRTSigs = new HashMap<String, ExtensionFunction>();
395  }
396 
397  for (TUserDefinedFunction udf : udfs) {
398  udfRTSigs.put(udf.name, toExtensionFunction(udf));
399  }
400 
401  for (TUserDefinedTableFunction udtf : udtfs) {
402  udfRTSigs.put(udtf.name, toExtensionFunction(udtf));
403  }
404 
405  // Avoid overwritting compiled and Loadtime UDFs:
406  for (String name : udfRTSigs.keySet()) {
407  if (extSigs.containsKey(name)) {
408  HEAVYDBLOGGER.error("Extension function `" + name
409  + "` exists. Skipping runtime extenension function with the same name.");
410  udfRTSigs.remove(name);
411  }
412  }
413  // udfRTSigsJson will contain only the signatures of UDFs:
414  udfRTSigsJson = ExtensionFunctionSignatureParser.signaturesToJson(udfRTSigs);
415  // Expose RT UDFs to Calcite server:
416  extSigs.putAll(udfRTSigs);
417  } else {
418  // currently only LoadTime UDTFs can be registered via calcite thrift interface
419  if (udtfSigs == null) {
420  udtfSigs = new HashMap<String, ExtensionFunction>();
421  }
422 
423  for (TUserDefinedTableFunction udtf : udtfs) {
424  udtfSigs.put(udtf.name, toExtensionFunction(udtf));
425  }
426 
427  extSigs.putAll(udtfSigs);
428  }
429 
430  calciteParserFactory.updateOperatorTable();
431  }
432 
433  private static ExtensionFunction toExtensionFunction(TUserDefinedFunction udf) {
434  List<ExtensionFunction.ExtArgumentType> args =
435  new ArrayList<ExtensionFunction.ExtArgumentType>();
436  for (TExtArgumentType atype : udf.argTypes) {
437  final ExtensionFunction.ExtArgumentType arg_type = toExtArgumentType(atype);
438  if (arg_type != ExtensionFunction.ExtArgumentType.Void) {
439  args.add(arg_type);
440  }
441  }
442  return new ExtensionFunction(args, toExtArgumentType(udf.retType));
443  }
444 
445  private static ExtensionFunction toExtensionFunction(TUserDefinedTableFunction udtf) {
446  int index = 0;
447  int out_index = 0;
448  List<String> names = new ArrayList<String>();
449  List<ExtensionFunction.ExtArgumentType> args =
450  new ArrayList<ExtensionFunction.ExtArgumentType>();
451  for (TExtArgumentType atype : udtf.sqlArgTypes) {
452  args.add(toExtArgumentType(atype));
453  Map<String, String> annot = udtf.annotations.get(index);
454  String name = annot.getOrDefault("name", "inp" + index);
455  if (atype == TExtArgumentType.Cursor && annot.containsKey("fields")) {
456  name = name + annot.get("fields");
457  }
458  names.add(name);
459  index++;
460  }
461  List<ExtensionFunction.ExtArgumentType> outs =
462  new ArrayList<ExtensionFunction.ExtArgumentType>();
463  for (TExtArgumentType otype : udtf.outputArgTypes) {
464  outs.add(toExtArgumentType(otype));
465  Map<String, String> annot = udtf.annotations.get(index);
466  names.add(annot.getOrDefault("name", "out" + out_index));
467  index++;
468  out_index++;
469  }
470  return new ExtensionFunction(
471  args, outs, names, udtf.annotations.get(udtf.annotations.size() - 1));
472  }
473 
474  private static ExtensionFunction.ExtArgumentType toExtArgumentType(
475  TExtArgumentType type) {
476  switch (type) {
477  case Int8:
478  return ExtensionFunction.ExtArgumentType.Int8;
479  case Int16:
480  return ExtensionFunction.ExtArgumentType.Int16;
481  case Int32:
482  return ExtensionFunction.ExtArgumentType.Int32;
483  case Int64:
484  return ExtensionFunction.ExtArgumentType.Int64;
485  case Float:
486  return ExtensionFunction.ExtArgumentType.Float;
487  case Double:
489  case Void:
490  return ExtensionFunction.ExtArgumentType.Void;
491  case PInt8:
492  return ExtensionFunction.ExtArgumentType.PInt8;
493  case PInt16:
494  return ExtensionFunction.ExtArgumentType.PInt16;
495  case PInt32:
496  return ExtensionFunction.ExtArgumentType.PInt32;
497  case PInt64:
498  return ExtensionFunction.ExtArgumentType.PInt64;
499  case PFloat:
500  return ExtensionFunction.ExtArgumentType.PFloat;
501  case PDouble:
502  return ExtensionFunction.ExtArgumentType.PDouble;
503  case PBool:
504  return ExtensionFunction.ExtArgumentType.PBool;
505  case Bool:
506  return ExtensionFunction.ExtArgumentType.Bool;
507  case ArrayInt8:
508  return ExtensionFunction.ExtArgumentType.ArrayInt8;
509  case ArrayInt16:
510  return ExtensionFunction.ExtArgumentType.ArrayInt16;
511  case ArrayInt32:
512  return ExtensionFunction.ExtArgumentType.ArrayInt32;
513  case ArrayInt64:
514  return ExtensionFunction.ExtArgumentType.ArrayInt64;
515  case ArrayFloat:
516  return ExtensionFunction.ExtArgumentType.ArrayFloat;
517  case ArrayDouble:
518  return ExtensionFunction.ExtArgumentType.ArrayDouble;
519  case ArrayBool:
520  return ExtensionFunction.ExtArgumentType.ArrayBool;
521  case ColumnInt8:
522  return ExtensionFunction.ExtArgumentType.ColumnInt8;
523  case ColumnInt16:
524  return ExtensionFunction.ExtArgumentType.ColumnInt16;
525  case ColumnInt32:
526  return ExtensionFunction.ExtArgumentType.ColumnInt32;
527  case ColumnInt64:
528  return ExtensionFunction.ExtArgumentType.ColumnInt64;
529  case ColumnFloat:
530  return ExtensionFunction.ExtArgumentType.ColumnFloat;
531  case ColumnDouble:
532  return ExtensionFunction.ExtArgumentType.ColumnDouble;
533  case ColumnBool:
534  return ExtensionFunction.ExtArgumentType.ColumnBool;
536  return ExtensionFunction.ExtArgumentType.ColumnTextEncodingDict;
537  case ColumnTimestamp:
538  return ExtensionFunction.ExtArgumentType.ColumnTimestamp;
539  case GeoPoint:
540  return ExtensionFunction.ExtArgumentType.GeoPoint;
541  case GeoLineString:
542  return ExtensionFunction.ExtArgumentType.GeoLineString;
543  case Cursor:
544  return ExtensionFunction.ExtArgumentType.Cursor;
545  case GeoPolygon:
546  return ExtensionFunction.ExtArgumentType.GeoPolygon;
547  case GeoMultiPolygon:
548  return ExtensionFunction.ExtArgumentType.GeoMultiPolygon;
549  case TextEncodingNone:
550  return ExtensionFunction.ExtArgumentType.TextEncodingNone;
551  case TextEncodingDict:
552  return ExtensionFunction.ExtArgumentType.TextEncodingDict;
553  case Timestamp:
554  return ExtensionFunction.ExtArgumentType.Timestamp;
555  case ColumnListInt8:
556  return ExtensionFunction.ExtArgumentType.ColumnListInt8;
557  case ColumnListInt16:
558  return ExtensionFunction.ExtArgumentType.ColumnListInt16;
559  case ColumnListInt32:
560  return ExtensionFunction.ExtArgumentType.ColumnListInt32;
561  case ColumnListInt64:
562  return ExtensionFunction.ExtArgumentType.ColumnListInt64;
563  case ColumnListFloat:
564  return ExtensionFunction.ExtArgumentType.ColumnListFloat;
565  case ColumnListDouble:
566  return ExtensionFunction.ExtArgumentType.ColumnListDouble;
567  case ColumnListBool:
568  return ExtensionFunction.ExtArgumentType.ColumnListBool;
570  return ExtensionFunction.ExtArgumentType.ColumnListTextEncodingDict;
571  default:
572  HEAVYDBLOGGER.error("toExtArgumentType: unknown type " + type);
573  return null;
574  }
575  }
576 
577  private static TCompletionHintType hintTypeToThrift(final SqlMonikerType type) {
578  switch (type) {
579  case COLUMN:
580  return TCompletionHintType.COLUMN;
581  case TABLE:
582  return TCompletionHintType.TABLE;
583  case VIEW:
584  return TCompletionHintType.VIEW;
585  case SCHEMA:
586  return TCompletionHintType.SCHEMA;
587  case CATALOG:
588  return TCompletionHintType.CATALOG;
589  case REPOSITORY:
590  return TCompletionHintType.REPOSITORY;
591  case FUNCTION:
592  return TCompletionHintType.FUNCTION;
593  case KEYWORD:
594  return TCompletionHintType.KEYWORD;
595  default:
596  return null;
597  }
598  }
599 }
Simplified core of GeoJSON Polygon coordinates definition.
Definition: heavydbTypes.h:366
CalciteServerHandler(int dbPort, String dataDir, String extensionFunctionsAstFile, SockTransportProperties skT, String udfAstFile)
void setRuntimeExtensionFunctions(List< TUserDefinedFunction > udfs, List< TUserDefinedTableFunction > udtfs, boolean isruntime)
Simplified core of GeoJSON MultiPolygon coordinates definition.
Definition: heavydbTypes.h:387
static ExtensionFunction.ExtArgumentType toExtArgumentType(TExtArgumentType type)
void updateMetadata(String catalog, String table)
std::string toString(const Executor::ExtModuleKinds &kind)
Definition: Execute.h:1453
Map< String, ExtensionFunction > udfRTSigs
static TCompletionHintType hintTypeToThrift(final SqlMonikerType type)
static ExtensionFunction toExtensionFunction(TUserDefinedTableFunction udtf)
static ExtensionFunction toExtensionFunction(TUserDefinedFunction udf)
string name
Definition: setup.in.py:72
TPlanResult process(String user, String session, String catalog, String queryText, TQueryParsingOption queryParsingOption, TOptimizationOption optimizationOption, List< TRestriction > trestrictions)
List< TCompletionHint > getCompletionHints(String user, String session, String catalog, List< String > visible_tables, String sql, int cursor)