public static void HandleLibFunc( CommonTokenStream tokenStream, EsperEPL2GrammarParser.LibFunctionContext ctx, ConfigurationInformation configurationInformation, EngineImportService engineImportService, IDictionary <ITree, ExprNode> astExprNodeMap, LazyAllocatedMap <ConfigurationPlugInAggregationMultiFunction, PlugInAggregationMultiFunctionFactory> plugInAggregations, string engineURI, ExpressionDeclDesc expressionDeclarations, ExprDeclaredService exprDeclaredService, IList <ExpressionScriptProvided> scriptExpressions, ContextDescriptor contextDescriptor, TableService tableService, StatementSpecRaw statementSpec, VariableService variableService) { var model = GetModel(ctx, tokenStream); var duckType = configurationInformation.EngineDefaults.ExpressionConfig.IsDuckTyping; var udfCache = configurationInformation.EngineDefaults.ExpressionConfig.IsUdfCache; // handle "some.xyz(...)" or "some.other.xyz(...)" if (model.ChainElements.Count == 1 && model.OptionalClassIdent != null && ASTTableExprHelper.CheckTableNameGetExprForProperty(tableService, model.OptionalClassIdent) == null) { var chainSpec = GetLibFunctionChainSpec(model.ChainElements[0], astExprNodeMap); var declaredNodeX = ExprDeclaredHelper.GetExistsDeclaredExpr(model.OptionalClassIdent, Collections.GetEmptyList <ExprNode>(), expressionDeclarations.Expressions, exprDeclaredService, contextDescriptor); if (declaredNodeX != null) { ExprNode exprNode = new ExprDotNode(Collections.SingletonList(chainSpec), duckType, udfCache); exprNode.AddChildNode(declaredNodeX); ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap); return; } IList <ExprChainedSpec> chainX = new List <ExprChainedSpec>(2); chainX.Add(new ExprChainedSpec(model.OptionalClassIdent, Collections.GetEmptyList <ExprNode>(), true)); chainX.Add(chainSpec); var dotNodeX = new ExprDotNode(chainX, configurationInformation.EngineDefaults.ExpressionConfig.IsDuckTyping, configurationInformation.EngineDefaults.ExpressionConfig.IsUdfCache); if (dotNodeX.IsVariableOp(variableService)) { statementSpec.HasVariables = true; } ASTExprHelper.ExprCollectAddSubNodesAddParentNode(dotNodeX, ctx, astExprNodeMap); return; } // try additional built-in single-row function ExprNode singleRowExtNode = engineImportService.ResolveSingleRowExtendedBuiltin(model.ChainElements[0].FuncName); if (singleRowExtNode != null) { if (model.ChainElements.Count == 1) { ASTExprHelper.ExprCollectAddSubNodesAddParentNode(singleRowExtNode, ctx, astExprNodeMap); return; } var spec = new List <ExprChainedSpec>(); EsperEPL2GrammarParser.LibFunctionArgsContext firstArgs = model.ChainElements[0].Args; var childExpressions = ASTLibFunctionHelper.GetExprNodesLibFunc(firstArgs, astExprNodeMap); singleRowExtNode.AddChildNodes(childExpressions); AddChainRemainderFromOffset(model.ChainElements, 1, spec, astExprNodeMap); var dotNodeX = new ExprDotNode(spec, configurationInformation.EngineDefaults.ExpressionConfig.IsDuckTyping, configurationInformation.EngineDefaults.ExpressionConfig.IsUdfCache); dotNodeX.AddChildNode(singleRowExtNode); ASTExprHelper.ExprCollectAddSubNodesAddParentNode(dotNodeX, ctx, astExprNodeMap); return; } // try plug-in single-row function try { var firstFunctionX = model.ChainElements[0].FuncName; var firstFunctionIsProperty = !model.ChainElements[0].HasLeftParen; var classMethodPair = engineImportService.ResolveSingleRow(firstFunctionX); IList <ExprChainedSpec> spec = new List <ExprChainedSpec>(); var firstArgs = model.ChainElements[0].Args; var childExpressions = ASTLibFunctionHelper.GetExprNodesLibFunc(firstArgs, astExprNodeMap); spec.Add(new ExprChainedSpec(classMethodPair.Second.MethodName, childExpressions, firstFunctionIsProperty)); AddChainRemainderFromOffset(model.ChainElements, 1, spec, astExprNodeMap); var plugin = new ExprPlugInSingleRowNode(firstFunctionX, classMethodPair.First, spec, classMethodPair.Second); ASTExprHelper.ExprCollectAddSubNodesAddParentNode(plugin, ctx, astExprNodeMap); return; } catch (EngineImportUndefinedException e) { // Not an single-row function } catch (EngineImportException e) { throw new IllegalStateException("Error resolving single-row function: " + e.Message, e); } // special case for min,max var firstFunction = model.ChainElements[0].FuncName; if ((firstFunction.ToLower().Equals("max")) || (firstFunction.ToLower().Equals("min")) || (firstFunction.ToLower().Equals("fmax")) || (firstFunction.ToLower().Equals("fmin"))) { var firstArgs = model.ChainElements[0].Args; HandleMinMax(firstFunction, firstArgs, astExprNodeMap); return; } // obtain chain with actual expressions IList <ExprChainedSpec> chain = new List <ExprChainedSpec>(); AddChainRemainderFromOffset(model.ChainElements, 0, chain, astExprNodeMap); // add chain element for class info, if any var distinct = model.ChainElements[0].Args != null && model.ChainElements[0].Args.DISTINCT() != null; if (model.OptionalClassIdent != null) { chain.Insert(0, new ExprChainedSpec(model.OptionalClassIdent, Collections.GetEmptyList <ExprNode>(), true)); distinct = false; } firstFunction = chain[0].Name; // try plug-in aggregation function var aggregationNode = ASTAggregationHelper.TryResolveAsAggregation(engineImportService, distinct, firstFunction, plugInAggregations, engineURI); if (aggregationNode != null) { var firstSpec = chain.Pluck(0); aggregationNode.AddChildNodes(firstSpec.Parameters); ExprNode exprNode; if (chain.IsEmpty()) { exprNode = aggregationNode; } else { exprNode = new ExprDotNode(chain, duckType, udfCache); exprNode.AddChildNode(aggregationNode); } ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap); return; } // try declared or alias expression var declaredNode = ExprDeclaredHelper.GetExistsDeclaredExpr(firstFunction, chain[0].Parameters, expressionDeclarations.Expressions, exprDeclaredService, contextDescriptor); if (declaredNode != null) { chain.RemoveAt(0); ExprNode exprNode; if (chain.IsEmpty()) { exprNode = declaredNode; } else { exprNode = new ExprDotNode(chain, duckType, udfCache); exprNode.AddChildNode(declaredNode); } ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap); return; } // try script var scriptNode = ExprDeclaredHelper.GetExistsScript(configurationInformation.EngineDefaults.ScriptsConfig.DefaultDialect, chain[0].Name, chain[0].Parameters, scriptExpressions, exprDeclaredService); if (scriptNode != null) { chain.RemoveAt(0); ExprNode exprNode; if (chain.IsEmpty()) { exprNode = scriptNode; } else { exprNode = new ExprDotNode(chain, duckType, udfCache); exprNode.AddChildNode(scriptNode); } ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap); return; } // try table var tableInfo = ASTTableExprHelper.CheckTableNameGetLibFunc(tableService, engineImportService, plugInAggregations, engineURI, firstFunction, chain); if (tableInfo != null) { ASTTableExprHelper.AddTableExpressionReference(statementSpec, tableInfo.First); chain = tableInfo.Second; ExprNode exprNode; if (chain.IsEmpty()) { exprNode = tableInfo.First; } else { exprNode = new ExprDotNode(chain, duckType, udfCache); exprNode.AddChildNode(tableInfo.First); } ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap); return; } // Could be a mapped property with an expression-parameter "mapped(expr)" or array property with an expression-parameter "array(expr)". ExprDotNode dotNode; if (chain.Count == 1) { dotNode = new ExprDotNode(chain, false, false); } else { dotNode = new ExprDotNode(chain, duckType, udfCache); } ASTExprHelper.ExprCollectAddSubNodesAddParentNode(dotNode, ctx, astExprNodeMap); }
private static ExprNode ResolveObject( IList <Chainable> chain, StatementSpecMapContext mapContext, Func <IList <Chainable>, ExprDotNodeImpl> dotNodeFunction) { var chainFirst = chain[0]; var chainFirstName = chainFirst.GetRootNameOrEmptyString(); var chainFirstParams = chainFirst.GetParametersOrEmpty(); // Handle script var scriptNode = ExprDeclaredHelper.GetExistsScript( mapContext.Configuration.Compiler.Scripts.DefaultDialect, chainFirstName, chainFirstParams, mapContext.Scripts, mapContext.MapEnv); if (scriptNode != null) { return(HandleScript(scriptNode, chain, dotNodeFunction)); } // Handle Table-related exceptions // A table will be "table.more" or "table[x, ...].more" var table = mapContext.TableCompileTimeResolver.Resolve(chainFirstName); if (table != null) { var nodes = HandleTable(chain, table, dotNodeFunction); if (nodes != null) { mapContext.TableExpressions.Add(nodes.Second); return(nodes.First); } } // Handle Variable-related exceptions // A variable will be "variable.more" or "variable[x, ...].more" var variable = mapContext.VariableCompileTimeResolver.Resolve(chainFirstName); if (variable != null) { mapContext.VariableNames.Add(variable.VariableName); return(HandleVariable(chain, variable, mapContext, dotNodeFunction)); } // Handle plug-in single-row functions var singleRow = TrySingleRow(mapContext, chainFirstName); if (singleRow != null) { return(HandleSingleRow(singleRow, chain)); } // try additional built-in single-row function var singleRowExtNode = mapContext.ImportService.ResolveSingleRowExtendedBuiltin(chainFirstName); if (singleRowExtNode != null) { return(HandleSingleRowExt(singleRowExtNode, chain, dotNodeFunction)); } // Handle declared-expression var declaredExpr = ExprDeclaredHelper.GetExistsDeclaredExpr( chainFirstName, chainFirstParams, mapContext.ExpressionDeclarations.Values, mapContext.ContextCompileTimeDescriptor, mapContext.MapEnv, mapContext.PlugInAggregations, mapContext.Scripts); if (declaredExpr != null) { mapContext.Add(declaredExpr.Second); return(HandleDeclaredExpr(declaredExpr.First, chain, dotNodeFunction)); } // Handle aggregation function var aggregationNode = (chainFirst is ChainableName) ? null : ASTAggregationHelper.TryResolveAsAggregation( mapContext.ImportService, chainFirst.IsDistinct, chainFirstName, mapContext.PlugInAggregations, mapContext.ClassProvidedExtension); if (aggregationNode != null) { return(HandleAggregation(aggregationNode, chain, dotNodeFunction)); } // Handle context property if (mapContext.ContextCompileTimeDescriptor != null && mapContext.ContextCompileTimeDescriptor.ContextPropertyRegistry.IsContextPropertyPrefix(chainFirstName)) { var subproperty = ToPlainPropertyString(chain, 1); return(new ExprContextPropertyNodeImpl(subproperty)); } // Handle min-max case var chainFirstLowerCase = chainFirstName.ToLowerInvariant(); if (!(chainFirst is ChainableName) && (chainFirstLowerCase.Equals("max", StringComparison.InvariantCultureIgnoreCase) || chainFirstLowerCase.Equals("min", StringComparison.InvariantCultureIgnoreCase) || chainFirstLowerCase.Equals("fmax", StringComparison.InvariantCultureIgnoreCase) || chainFirstLowerCase.Equals("fmin", StringComparison.InvariantCultureIgnoreCase))) { return(HandleMinMax(chainFirstLowerCase, chain, dotNodeFunction)); } // Handle class name var classChain = HandleClassPrefixedNonProp(mapContext, chain); if (classChain != null) { return(dotNodeFunction.Invoke(classChain)); } return(null); }