Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }