17 package com.mapd.parser.server;
19 import static com.mapd.calcite.parser.HeavyDBParser.CURRENT_PARSER;
29 import org.apache.calcite.runtime.CalciteContextException;
30 import org.apache.calcite.sql.SqlNode;
31 import org.apache.calcite.sql.parser.SqlParseException;
32 import org.apache.calcite.sql.type.SqlTypeName;
33 import org.apache.calcite.sql.validate.SqlMoniker;
34 import org.apache.calcite.sql.validate.SqlMonikerType;
35 import org.apache.calcite.tools.RelConversionException;
36 import org.apache.calcite.tools.ValidationException;
37 import org.apache.calcite.util.Pair;
38 import org.apache.commons.pool.PoolableObjectFactory;
39 import org.apache.commons.pool.impl.GenericObjectPool;
40 import org.apache.thrift.TException;
41 import org.apache.thrift.server.TServer;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
45 import java.io.IOException;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.HashMap;
49 import java.util.List;
51 import java.util.stream.Collectors;
53 import ai.heavy.thrift.calciteserver.CalciteServer;
54 import ai.heavy.thrift.calciteserver.InvalidParseRequest;
55 import ai.heavy.thrift.calciteserver.TAccessedQueryObjects;
56 import ai.heavy.thrift.calciteserver.TCompletionHint;
57 import ai.heavy.thrift.calciteserver.TCompletionHintType;
58 import ai.heavy.thrift.calciteserver.TExtArgumentType;
59 import ai.heavy.thrift.calciteserver.TFilterPushDownInfo;
60 import ai.heavy.thrift.calciteserver.TOptimizationOption;
61 import ai.heavy.thrift.calciteserver.TPlanResult;
62 import ai.heavy.thrift.calciteserver.TQueryParsingOption;
63 import ai.heavy.thrift.calciteserver.TRestriction;
64 import ai.heavy.thrift.calciteserver.TUserDefinedFunction;
65 import ai.heavy.thrift.calciteserver.TUserDefinedTableFunction;
68 final static Logger
HEAVYDBLOGGER = LoggerFactory.getLogger(CalciteServerHandler.class);
86 Map<String, ExtensionFunction>
udtfSigs = null;
89 private Map<String, ExtensionFunction>
extSigs = null;
96 String extensionFunctionsAstFile,
102 Map<String, ExtensionFunction> udfSigs = null;
105 extSigs = ExtensionFunctionSignatureParser.parse(extensionFunctionsAstFile);
106 }
catch (IOException ex) {
108 "Could not load extension function signatures: " + ex.getMessage(), ex);
113 if (!udfAstFile.isEmpty()) {
114 udfSigs = ExtensionFunctionSignatureParser.parseUdfAst(udfAstFile);
116 }
catch (IOException ex) {
118 "Could not load udf function signatures: " + ex.getMessage(), ex);
120 udfSigsJson = ExtensionFunctionSignatureParser.signaturesToJson(udfSigs);
124 if (!udfAstFile.isEmpty()) {
125 extSigs.putAll(udfSigs);
135 public void ping() throws TException {
136 HEAVYDBLOGGER.debug(
"Ping hit");
144 TQueryParsingOption queryParsingOption,
145 TOptimizationOption optimizationOption,
146 List<TRestriction> trestrictions)
throws InvalidParseRequest, TException {
147 long timer = System.currentTimeMillis();
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);
159 List<Restriction> rests = null;
160 if (trestrictions != null && !trestrictions.isEmpty()) {
161 rests =
new ArrayList<>();
162 for (TRestriction trestriction : trestrictions) {
167 trestriction.values);
172 HEAVYDBLOGGER.debug(
"process was called User: " + user +
" Catalog: " + catalog
173 +
" sql: " + queryText);
174 parser.setUser(dbUser);
175 CURRENT_PARSER.set(
parser);
179 boolean buildRATreeFromRAString =
false;
180 if (queryText.startsWith(
"execute calcite")) {
181 queryText = queryText.replaceFirst(
"execute calcite",
"");
182 buildRATreeFromRAString =
true;
186 queryText = queryText.trim();
188 if (queryText.length() > 0 && queryText.charAt(queryText.length() - 1) ==
';') {
189 queryText = queryText.substring(0, queryText.length() - 1);
193 TAccessedQueryObjects primaryAccessedObjects =
new TAccessedQueryObjects();
194 TAccessedQueryObjects resolvedAccessedObjects =
new TAccessedQueryObjects();
196 final List<HeavyDBParserOptions.FilterPushDownInfo> filterPushDownInfo =
198 for (
final TFilterPushDownInfo req : optimizationOption.filter_push_down_info) {
199 filterPushDownInfo.add(
new HeavyDBParserOptions.FilterPushDownInfo(
200 req.input_prev, req.input_start, req.input_next));
203 queryParsingOption.legacy_syntax,
204 queryParsingOption.is_explain,
205 queryParsingOption.is_explain_detail,
206 optimizationOption.is_view_optimize,
207 optimizationOption.enable_watchdog,
208 optimizationOption.distributed_mode);
210 if (!buildRATreeFromRAString) {
211 Pair<String, SqlIdentifierCapturer>
res;
214 res = parser.process(queryText, parserOptions);
215 jsonResult = res.left;
216 capturer = res.right;
218 primaryAccessedObjects.tables_selected_from =
new ArrayList<>(capturer.selects);
219 primaryAccessedObjects.tables_inserted_into =
new ArrayList<>(capturer.inserts);
220 primaryAccessedObjects.tables_updated_in =
new ArrayList<>(capturer.updates);
221 primaryAccessedObjects.tables_deleted_from =
new ArrayList<>(capturer.deletes);
226 resolvedAccessedObjects.tables_selected_from =
227 new ArrayList<>(parser.resolveSelectIdentifiers(capturer));
228 resolvedAccessedObjects.tables_inserted_into =
new ArrayList<>(capturer.inserts);
229 resolvedAccessedObjects.tables_updated_in =
new ArrayList<>(capturer.updates);
230 resolvedAccessedObjects.tables_deleted_from =
new ArrayList<>(capturer.deletes);
235 parser.buildRATreeAndPerformQueryOptimization(queryText, parserOptions);
237 }
catch (SqlParseException ex) {
238 String msg =
"SQL Error: " + ex.getMessage();
239 HEAVYDBLOGGER.error(msg);
240 throw new InvalidParseRequest(-2, msg);
241 }
catch (org.apache.calcite.tools.ValidationException ex) {
242 String msg =
"SQL Error: " + ex.getMessage();
243 if (ex.getCause() != null
244 && (ex.getCause().getClass() == CalciteContextException.class)) {
245 msg =
"SQL Error: " + ex.getCause().getMessage();
247 HEAVYDBLOGGER.error(msg);
248 throw new InvalidParseRequest(-3, msg);
249 }
catch (CalciteContextException ex) {
250 String msg = ex.getMessage();
251 HEAVYDBLOGGER.error(msg);
252 throw new InvalidParseRequest(-6, msg);
253 }
catch (RelConversionException ex) {
254 String msg =
"Failed to generate relational algebra for query " + ex.getMessage();
255 HEAVYDBLOGGER.error(msg, ex);
256 throw new InvalidParseRequest(-5, msg);
257 }
catch (Throwable ex) {
258 HEAVYDBLOGGER.error(ex.getClass().
toString());
259 String msg = ex.getMessage();
260 HEAVYDBLOGGER.error(msg, ex);
261 throw new InvalidParseRequest(-4, msg);
263 CURRENT_PARSER.set(null);
266 parserPool.returnObject(
parser);
267 }
catch (Exception ex) {
268 String msg =
"Could not return parse object: " + ex.getMessage();
269 HEAVYDBLOGGER.error(msg, ex);
270 throw new InvalidParseRequest(-7, msg);
274 TPlanResult
result =
new TPlanResult();
275 result.primary_accessed_objects = primaryAccessedObjects;
276 result.resolved_accessed_objects = resolvedAccessedObjects;
277 result.plan_result = jsonResult;
278 result.execution_time_ms = System.currentTimeMillis() - timer;
286 HEAVYDBLOGGER.debug(
"Shutdown calcite java server");
292 return this.extSigsJson;
297 return this.udfSigsJson;
302 return this.udfRTSigsJson;
313 "Received invalidation from server for " + catalog +
" : " + table);
314 long timer = System.currentTimeMillis();
319 }
catch (Exception ex) {
320 String msg =
"Could not get Parse Item from pool: " + ex.getMessage();
321 HEAVYDBLOGGER.error(msg, ex);
324 CURRENT_PARSER.set(
parser);
326 parser.updateMetaData(catalog, table);
328 CURRENT_PARSER.set(null);
331 HEAVYDBLOGGER.debug(
"Returning object to pool");
332 parserPool.returnObject(
parser);
333 }
catch (Exception ex) {
334 String msg =
"Could not return parse object: " + ex.getMessage();
335 HEAVYDBLOGGER.error(msg, ex);
344 List<String> visible_tables,
346 int cursor)
throws TException {
351 }
catch (Exception ex) {
352 String msg =
"Could not get Parse Item from pool: " + ex.getMessage();
353 HEAVYDBLOGGER.error(msg, ex);
354 throw new TException(msg);
357 HEAVYDBLOGGER.debug(
"getCompletionHints was called User: " + user
358 +
" Catalog: " + catalog +
" sql: " + sql);
359 parser.setUser(dbUser);
360 CURRENT_PARSER.set(
parser);
362 HeavyDBPlanner.CompletionResult completion_result;
364 completion_result = parser.getCompletionHints(sql, cursor, visible_tables);
365 }
catch (Exception ex) {
366 String msg =
"Could not retrieve completion hints: " + ex.getMessage();
367 HEAVYDBLOGGER.error(msg, ex);
368 return new ArrayList<>();
370 CURRENT_PARSER.set(null);
373 parserPool.returnObject(
parser);
374 }
catch (Exception ex) {
375 String msg =
"Could not return parse object: " + ex.getMessage();
376 HEAVYDBLOGGER.error(msg, ex);
377 throw new InvalidParseRequest(-4, msg);
380 List<TCompletionHint>
result =
new ArrayList<>();
381 for (
final SqlMoniker hint : completion_result.hints) {
383 hint.getFullyQualifiedNames(),
384 completion_result.replaced));
391 List<TUserDefinedTableFunction> udtfs,
400 udfRTSigs =
new HashMap<String, ExtensionFunction>();
403 for (TUserDefinedFunction udf : udfs) {
407 for (TUserDefinedTableFunction udtf : udtfs) {
414 HEAVYDBLOGGER.error(
"Extension function `" +
name
415 +
"` exists. Skipping runtime extenension function with the same name.");
416 udfRTSigs.remove(
name);
426 udtfSigs =
new HashMap<String, ExtensionFunction>();
429 for (TUserDefinedTableFunction udtf : udtfs) {
436 calciteParserFactory.updateOperatorTable();
440 TUserDefinedFunction udf,
boolean isruntime) {
441 List<ExtensionFunction.ExtArgumentType>
args =
442 new ArrayList<ExtensionFunction.ExtArgumentType>();
443 for (TExtArgumentType atype : udf.argTypes) {
453 TUserDefinedTableFunction udtf,
boolean isruntime) {
454 int sqlInputArgIdx = 0;
456 int outputArgIdx = 0;
457 List<String> names =
new ArrayList<String>();
458 List<ExtensionFunction.ExtArgumentType>
args =
new ArrayList<>();
459 Map<String, List<ExtensionFunction.ExtArgumentType>> cursor_field_types =
461 Map<String, Comparable<?>> default_values =
new HashMap<>();
462 for (TExtArgumentType atype : udtf.sqlArgTypes) {
464 Map<String, String> annot = udtf.annotations.get(sqlInputArgIdx);
465 String
name = annot.getOrDefault(
"name",
"inp" + sqlInputArgIdx);
466 if (atype == TExtArgumentType.Cursor) {
467 String field_names_annot = annot.getOrDefault(
"fields",
"");
468 List<ExtensionFunction.ExtArgumentType> field_types =
new ArrayList<>();
469 if (field_names_annot.length() > 0) {
470 String[] field_names =
471 field_names_annot.substring(1, field_names_annot.length() - 1)
473 for (
int i = 0; i < field_names.length; i++) {
483 name = name + field_names_annot;
484 cursor_field_types.put(
name, field_types);
486 String default_value_annot = annot.getOrDefault(
"default", null);
487 if (default_value_annot != null) {
489 if (default_val != null) {
490 default_values.put(
name, default_val);
499 List<ExtensionFunction.ExtArgumentType> outs =
new ArrayList<>();
500 for (TExtArgumentType otype : udtf.outputArgTypes) {
502 Map<String, String> annot = udtf.annotations.get(sqlInputArgIdx);
503 names.add(annot.getOrDefault(
"name",
"out" + outputArgIdx));
510 udtf.annotations.get(udtf.annotations.size() - 1),
516 String annot, TExtArgumentType input_type) {
517 switch (input_type) {
519 return new Byte(annot);
521 return new Short(annot);
525 return new Long(annot);
527 return new Float(annot);
531 return new Boolean(annot);
535 HEAVYDBLOGGER.error(
"Unsupported type in UDTF 'default' annotation: "
536 + input_type.toString());
542 TExtArgumentType
type) {
545 return ExtensionFunction.ExtArgumentType.Int8;
547 return ExtensionFunction.ExtArgumentType.Int16;
549 return ExtensionFunction.ExtArgumentType.Int32;
551 return ExtensionFunction.ExtArgumentType.Int64;
553 return ExtensionFunction.ExtArgumentType.Float;
557 return ExtensionFunction.ExtArgumentType.Void;
559 return ExtensionFunction.ExtArgumentType.PInt8;
561 return ExtensionFunction.ExtArgumentType.PInt16;
563 return ExtensionFunction.ExtArgumentType.PInt32;
565 return ExtensionFunction.ExtArgumentType.PInt64;
567 return ExtensionFunction.ExtArgumentType.PFloat;
569 return ExtensionFunction.ExtArgumentType.PDouble;
571 return ExtensionFunction.ExtArgumentType.PBool;
573 return ExtensionFunction.ExtArgumentType.Bool;
575 return ExtensionFunction.ExtArgumentType.ArrayInt8;
577 return ExtensionFunction.ExtArgumentType.ArrayInt16;
579 return ExtensionFunction.ExtArgumentType.ArrayInt32;
581 return ExtensionFunction.ExtArgumentType.ArrayInt64;
583 return ExtensionFunction.ExtArgumentType.ArrayFloat;
585 return ExtensionFunction.ExtArgumentType.ArrayDouble;
587 return ExtensionFunction.ExtArgumentType.ArrayBool;
589 return ExtensionFunction.ExtArgumentType.ArrayTextEncodingDict;
591 return ExtensionFunction.ExtArgumentType.ColumnInt8;
593 return ExtensionFunction.ExtArgumentType.ColumnInt16;
595 return ExtensionFunction.ExtArgumentType.ColumnInt32;
597 return ExtensionFunction.ExtArgumentType.ColumnInt64;
599 return ExtensionFunction.ExtArgumentType.ColumnFloat;
601 return ExtensionFunction.ExtArgumentType.ColumnDouble;
603 return ExtensionFunction.ExtArgumentType.ColumnBool;
605 return ExtensionFunction.ExtArgumentType.ColumnTextEncodingDict;
607 return ExtensionFunction.ExtArgumentType.ColumnTimestamp;
617 return ExtensionFunction.ExtArgumentType.Cursor;
623 return ExtensionFunction.ExtArgumentType.TextEncodingNone;
625 return ExtensionFunction.ExtArgumentType.TextEncodingDict;
627 return ExtensionFunction.ExtArgumentType.Timestamp;
629 return ExtensionFunction.ExtArgumentType.ColumnListInt8;
631 return ExtensionFunction.ExtArgumentType.ColumnListInt16;
633 return ExtensionFunction.ExtArgumentType.ColumnListInt32;
635 return ExtensionFunction.ExtArgumentType.ColumnListInt64;
637 return ExtensionFunction.ExtArgumentType.ColumnListFloat;
639 return ExtensionFunction.ExtArgumentType.ColumnListDouble;
641 return ExtensionFunction.ExtArgumentType.ColumnListBool;
643 return ExtensionFunction.ExtArgumentType.ColumnListTextEncodingDict;
645 return ExtensionFunction.ExtArgumentType.ColumnArrayInt8;
647 return ExtensionFunction.ExtArgumentType.ColumnArrayInt16;
649 return ExtensionFunction.ExtArgumentType.ColumnArrayInt32;
651 return ExtensionFunction.ExtArgumentType.ColumnArrayInt64;
653 return ExtensionFunction.ExtArgumentType.ColumnArrayFloat;
655 return ExtensionFunction.ExtArgumentType.ColumnArrayDouble;
657 return ExtensionFunction.ExtArgumentType.ColumnArrayBool;
659 return ExtensionFunction.ExtArgumentType.ColumnArrayTextEncodingDict;
661 return ExtensionFunction.ExtArgumentType.ColumnListArrayInt8;
663 return ExtensionFunction.ExtArgumentType.ColumnListArrayInt16;
665 return ExtensionFunction.ExtArgumentType.ColumnListArrayInt32;
667 return ExtensionFunction.ExtArgumentType.ColumnListArrayInt64;
669 return ExtensionFunction.ExtArgumentType.ColumnListArrayFloat;
671 return ExtensionFunction.ExtArgumentType.ColumnListArrayDouble;
673 return ExtensionFunction.ExtArgumentType.ColumnListArrayBool;
675 return ExtensionFunction.ExtArgumentType.ColumnListArrayTextEncodingDict;
677 return ExtensionFunction.ExtArgumentType.DayTimeInterval;
679 return ExtensionFunction.ExtArgumentType.YearMonthTimeInterval;
681 return ExtensionFunction.ExtArgumentType.ColumnGeoPoint;
683 return ExtensionFunction.ExtArgumentType.ColumnGeoLineString;
685 return ExtensionFunction.ExtArgumentType.ColumnGeoPolygon;
687 return ExtensionFunction.ExtArgumentType.ColumnGeoMultiPoint;
689 return ExtensionFunction.ExtArgumentType.ColumnGeoMultiLineString;
691 return ExtensionFunction.ExtArgumentType.ColumnGeoMultiPolygon;
693 return ExtensionFunction.ExtArgumentType.ColumnListGeoPoint;
695 return ExtensionFunction.ExtArgumentType.ColumnListGeoLineString;
697 return ExtensionFunction.ExtArgumentType.ColumnListGeoPolygon;
699 return ExtensionFunction.ExtArgumentType.ColumnListGeoMultiPoint;
701 return ExtensionFunction.ExtArgumentType.ColumnListGeoMultiLineString;
703 return ExtensionFunction.ExtArgumentType.ColumnListGeoMultiPolygon;
705 return ExtensionFunction.ExtArgumentType.ArrayTextEncodingNone;
707 return ExtensionFunction.ExtArgumentType.ColumnTextEncodingNone;
709 return ExtensionFunction.ExtArgumentType.ColumnListTextEncodingNone;
711 return ExtensionFunction.ExtArgumentType.ColumnArrayTextEncodingNone;
713 return ExtensionFunction.ExtArgumentType.ColumnListArrayTextEncodingNone;
715 HEAVYDBLOGGER.error(
"toExtArgumentType: unknown type " +
type);
723 return TCompletionHintType.COLUMN;
725 return TCompletionHintType.TABLE;
727 return TCompletionHintType.VIEW;
729 return TCompletionHintType.SCHEMA;
731 return TCompletionHintType.CATALOG;
733 return TCompletionHintType.REPOSITORY;
735 return TCompletionHintType.FUNCTION;
737 return TCompletionHintType.KEYWORD;
struct GeoLineStringStruct GeoLineString
static Comparable<?> getDefaultValueForAnnot(String annot, TExtArgumentType input_type)
struct GeoPointStruct GeoPoint
Simplified core of GeoJSON Polygon coordinates definition.
final CalciteParserFactory calciteParserFactory
CalciteServerHandler(int dbPort, String dataDir, String extensionFunctionsAstFile, SockTransportProperties skT, String udfAstFile)
void setRuntimeExtensionFunctions(List< TUserDefinedFunction > udfs, List< TUserDefinedTableFunction > udtfs, boolean isruntime)
Map< String, ExtensionFunction > udtfSigs
Simplified core of GeoJSON MultiPolygon coordinates definition.
static ExtensionFunction.ExtArgumentType toExtArgumentType(TExtArgumentType type)
String getExtensionFunctionWhitelist()
void setServer(TServer s)
void updateMetadata(String catalog, String table)
String getUserDefinedFunctionWhitelist()
final GenericObjectPool parserPool
Map< String, ExtensionFunction > extSigs
std::string toString(const Executor::ExtModuleKinds &kind)
struct GeoMultiPointStruct GeoMultiPoint
Map< String, ExtensionFunction > udfRTSigs
struct GeoMultiLineStringStruct GeoMultiLineString
static TCompletionHintType hintTypeToThrift(final SqlMonikerType type)
final List< Map< String, String > > annotations
static ExtensionFunction toExtensionFunction(TUserDefinedFunction udf, boolean isruntime)
static ExtensionFunction toExtensionFunction(TUserDefinedTableFunction udtf, boolean isruntime)
struct GeoMultiPolygonStruct GeoMultiPolygon
static final Logger HEAVYDBLOGGER
struct GeoPolygonStruct GeoPolygon
String getRuntimeExtensionFunctionWhitelist()
SockTransportProperties skT
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)