Пример #1
0
        // Resolve symbols in the syntax tree by finding referenced schema elements.
        // This also performes schema population by appending columns if they cannot be found.
        // Schema population is performed if the corresponding flag is true.
        protected void Bind()
        {
            // NOTE: This should be removed or moved to the expression. Here we store non-syntactic part of the definition in columndef and then set the expression. Maybe we should have syntactic annotation for APPEND flag (output result annotation, what to do with the output).
            if (formulaExpr.DefinitionType == ColumnDefinitionType.LINK)
            {
                // Adjust the expression according to other parameters of the definition
                if (IsAppendData)
                {
                    formulaExpr.Action = ActionType.APPEND;
                }
                else
                {
                    formulaExpr.Action = ActionType.READ;
                }
            }

            // General parameters
            DcSpace Workspace = Column.Input.Schema.Space;

            if (Column.Input.Schema is SchemaCsv) // Import from CSV
            {
                // Prepare parameter variables for the expression
                DcTable thisTable = Column.Input;

                thisVariable            = new Variable(thisTable.Schema.Name, thisTable.Name, "this");
                thisVariable.TypeSchema = thisTable.Schema;
                thisVariable.TypeTable  = thisTable;

                // Parameterize expression and resolve it (bind names to real objects)
                formulaExpr.OutputVariable.SchemaName = Column.Output.Schema.Name;
                formulaExpr.OutputVariable.TypeName   = Column.Output.Name;
                formulaExpr.OutputVariable.TypeSchema = Column.Output.Schema;
                formulaExpr.OutputVariable.TypeTable  = Column.Output;

                formulaExpr.Resolve(Workspace, new List <DcVariable>()
                {
                    thisVariable
                });
            }
            else if (formulaExpr.DefinitionType == ColumnDefinitionType.ARITHMETIC || formulaExpr.DefinitionType == ColumnDefinitionType.LINK)
            {
                // Prepare parameter variables for the expression
                DcTable thisTable = Column.Input;

                thisVariable            = new Variable(thisTable.Schema.Name, thisTable.Name, "this");
                thisVariable.TypeSchema = thisTable.Schema;
                thisVariable.TypeTable  = thisTable;

                // Parameterize expression and resolve it (bind names to real objects)
                formulaExpr.OutputVariable.SchemaName = Column.Output.Schema.Name;
                formulaExpr.OutputVariable.TypeName   = Column.Output.Name;
                formulaExpr.OutputVariable.TypeSchema = Column.Output.Schema;
                formulaExpr.OutputVariable.TypeTable  = Column.Output;

                formulaExpr.Resolve(Workspace, new List <DcVariable>()
                {
                    thisVariable
                });
            }
            else if (formulaExpr.DefinitionType == ColumnDefinitionType.AGGREGATION)
            {
                // Aassert: FactTable.GroupFormula + ThisSet.ThisFunc = FactTable.MeasureFormula
                // Aassert: if LoopSet == ThisSet then GroupCode = null, ThisFunc = MeasureCode

                // Facts
                factsExpr = formulaExpr.GetChild("facts").GetChild(0);

                // This table and variable
                string  thisTableName = factsExpr.Name;
                DcTable thisTable     = Column.Input.Schema.GetSubTable(thisTableName);

                thisVariable            = new Variable(thisTable.Schema.Name, thisTable.Name, "this");
                thisVariable.TypeSchema = thisTable.Schema;
                thisVariable.TypeTable  = thisTable;

                // Groups
                groupExpr = formulaExpr.GetChild("groups").GetChild(0);

                groupExpr.Resolve(Workspace, new List <DcVariable>()
                {
                    thisVariable
                });

                groupVariable            = new Variable(Column.Input.Schema.Name, Column.Input.Name, "this");
                groupVariable.TypeSchema = Column.Input.Schema;
                groupVariable.TypeTable  = Column.Input;

                // Measure
                measureExpr = formulaExpr.GetChild("measure").GetChild(0);

                measureExpr.Resolve(Workspace, new List <DcVariable>()
                {
                    thisVariable
                });

                measureVariable            = new Variable(Column.Output.Schema.Name, Column.Output.Name, "value");
                measureVariable.TypeSchema = Column.Output.Schema;
                measureVariable.TypeTable  = Column.Output;

                // Updater/aggregation function
                ExprNode updaterExpr = formulaExpr.GetChild("aggregator").GetChild(0);
                outputExpr = ExprNode.CreateUpdater(Column, updaterExpr.Name);

                outputExpr.Resolve(Workspace, new List <DcVariable>()
                {
                    groupVariable, measureVariable
                });
            }
            else
            {
                throw new NotImplementedException("This type of column definition is not implemented.");
            }
        }