Example #1
0
        public static ExprNode ProcessDot(
            bool useChainAsIs,
            bool resolveObjects,
            IList <Chainable> chain,
            StatementSpecMapContext mapContext)
        {
            if (chain.IsEmpty())
            {
                throw new ArgumentException("Empty chain");
            }

            Func <IList <Chainable>, ExprDotNodeImpl> dotNodeFunction = chainSpec => {
                var dotNode = new ExprDotNodeImpl(
                    chainSpec,
                    mapContext.Configuration.Compiler.Expression.IsDuckTyping,
                    mapContext.Configuration.Compiler.Expression.IsUdfCache);
                // add any variables that are referenced
                var variable = dotNode.IsVariableOpGetName(mapContext.VariableCompileTimeResolver);
                if (variable != null)
                {
                    mapContext.VariableNames.Add(variable.VariableName);
                }

                return(dotNode);
            };

            // Resolve objects if required
            if (resolveObjects)
            {
                var resolved = ResolveObject(chain, mapContext, dotNodeFunction);
                if (resolved != null)
                {
                    return(resolved);
                }
            }

            // Check if we are dealing with a plain event property expression, i.e. one without any eventstream-dependent expression
            var plain = DeterminePlainProperty(chain);

            if (plain)
            {
                return(HandlePlain(chain, dotNodeFunction, useChainAsIs));
            }

            return(HandleNonPlain(chain, dotNodeFunction));
        }
Example #2
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.Expression.IsDuckTyping;
            var udfCache = configurationInformation.EngineDefaults.Expression.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)
                {
                    var exprNode = new ExprDotNodeImpl(Collections.SingletonList(chainSpec), duckType, udfCache);
                    exprNode.AddChildNode(declaredNodeX);
                    ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap);
                    return;
                }

                var chainX = new List <ExprChainedSpec>(2);
                chainX.Add(new ExprChainedSpec(model.OptionalClassIdent, Collections.GetEmptyList <ExprNode>(), true));
                chainX.Add(chainSpec);
                var dotNodeX = new ExprDotNodeImpl(
                    chainX, configurationInformation.EngineDefaults.Expression.IsDuckTyping,
                    configurationInformation.EngineDefaults.Expression.IsUdfCache);
                if (dotNodeX.IsVariableOpGetName(variableService) != null)
                {
                    statementSpec.HasVariables = true;
                }
                ASTExprHelper.ExprCollectAddSubNodesAddParentNode(dotNodeX, ctx, astExprNodeMap);
                return;
            }

            // try additional built-in single-row function
            var 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>();
                var firstArgs        = model.ChainElements[0].Args;
                var childExpressions = GetExprNodesLibFunc(firstArgs, astExprNodeMap);
                singleRowExtNode.AddChildNodes(childExpressions);
                AddChainRemainderFromOffset(model.ChainElements, 1, spec, astExprNodeMap);
                var dotNodeX = new ExprDotNodeImpl(
                    spec, configurationInformation.EngineDefaults.Expression.IsDuckTyping,
                    configurationInformation.EngineDefaults.Expression.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);
                var spec             = new List <ExprChainedSpec>();
                var firstArgs        = model.ChainElements[0].Args;
                var childExpressions = 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)
            {
                // 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.ToLowerInvariant().Equals("max")) || (firstFunction.ToLowerInvariant().Equals("min")) ||
                (firstFunction.ToLowerInvariant().Equals("fmax")) || (firstFunction.ToLowerInvariant().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.DeleteAt(0);
                aggregationNode.AddChildNodes(firstSpec.Parameters);
                ExprNode exprNode;
                if (chain.IsEmpty())
                {
                    exprNode = aggregationNode;
                }
                else
                {
                    exprNode = new ExprDotNodeImpl(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 ExprDotNodeImpl(chain, duckType, udfCache);
                    exprNode.AddChildNode(declaredNode);
                }
                ASTExprHelper.ExprCollectAddSubNodesAddParentNode(exprNode, ctx, astExprNodeMap);
                return;
            }

            // try script
            var scriptNode =
                ExprDeclaredHelper.GetExistsScript(
                    configurationInformation.EngineDefaults.Scripts.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 ExprDotNodeImpl(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 ExprDotNodeImpl(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 ExprDotNodeImpl(chain, false, false);
            }
            else
            {
                dotNode = new ExprDotNodeImpl(chain, duckType, udfCache);
            }
            ASTExprHelper.ExprCollectAddSubNodesAddParentNode(dotNode, ctx, astExprNodeMap);
        }