Пример #1
0
        private void OkCommand_Executed(object state)
        {
            DcSchema schema = Column.Input.Schema;

            // Column name
            if (IsWhere)
            {
                SourceTable.Name = sourceTableName.Text;
            }
            else
            {
                Column.Name = newColumnName.Text;
            }

            ExprNode expr = null;

            if (ExpressionModel == null || ExpressionModel.Count == 0)
            {
                expr = null;
            }
            else
            {
                expr = ExpressionModel[0];
            }

            if (IsWhere) // Expression is part of the table Where definition
            {
                if (expr != null)
                {
                    expr.OutputVariable.TypeName  = "Boolean";
                    expr.OutputVariable.TypeTable = schema.GetPrimitive("Boolean");
                }

                SourceTable.Definition.WhereExpr = expr;
            }
            else // Expression belongs to the column definition
            {
                // Column type
                // Derive output type of the expression and use it to set the type of the column.
                // Alternatively, the type could be chosen by the user precisely as it is done for link columns.
                expr.Resolve(schema.Workspace, new List <DcVariable>()
                {
                    new Variable(SourceTable, "this")
                });
                Column.Output = expr.OutputVariable.TypeTable;

                Column.Definition.FormulaExpr = expr;
            }

            this.DialogResult = true;
        }
Пример #2
0
        public void Populate() 
        {
            if (DefinitionType == TableDefinitionType.FREE)
            {
                return; // Nothing to do
            }

            Length = 0;

            if (DefinitionType == TableDefinitionType.PROJECTION) // There are import dimensions so copy data from another set (projection of another set)
            {
                List<DcColumn> inColumns = InputColumns.Where(d => d.GetData().IsAppendData).ToList();

                foreach(DcColumn inColumn in inColumns)
                {
                    inColumn.GetData().Translate();
                    inColumn.GetData().Evaluate(); // Delegate to column evaluation - it will add records from column expression
                }
            }
            else if (DefinitionType == TableDefinitionType.PRODUCT) // Product of local sets (no project/de-project from another set)
            {
                // Input variable for where formula
                DcVariable thisVariable = new Variable(this.Schema.Name, this.Name, "this");
                thisVariable.TypeSchema = this.Schema;
                thisVariable.TypeTable = this;

                // Evaluator expression for where formula
                ExprNode outputExpr = this.WhereExpr;
                if(outputExpr != null)
                {
                    outputExpr.OutputVariable.SchemaName = this.Schema.Name;
                    outputExpr.OutputVariable.TypeName = "Boolean";
                    outputExpr.OutputVariable.TypeSchema = this.Schema;
                    outputExpr.OutputVariable.TypeTable = this.Schema.GetPrimitiveType("Boolean");
                    outputExpr.Resolve(this.Space, new List<DcVariable>() { thisVariable });

                    outputExpr.EvaluateBegin();
                }

                DcTableWriter tableWriter = this.GetTableWriter();
                tableWriter.Open();

                //
                // Find all local greater dimensions to be varied (including the super-dim)
                //
                DcColumn[] cols = Columns.Where(x => x.IsKey && !x.IsPrimitive).ToArray();
                int colCount = cols.Length; // Dimensionality - how many free dimensions
                object[] vals = new object[colCount]; // A record with values for each free dimension being varied

                // Prepare columns
                foreach (DcColumn col in cols)
                {
                    col.GetData().AutoIndex = true; // We need true to correctly evaluate where condition and correctly remove last element if it is wrong
                    //col.GetData().Nullify();
                }

                //
                // The current state of the search procedure
                //
                Rowid[] lengths = new Rowid[colCount]; // Size of each dimension being varied (how many offsets in each dimension)
                for (int i = 0; i < colCount; i++) lengths[i] = cols[i].Output.GetData().Length;

                Rowid[] offsets = new Rowid[colCount]; // The current point/offset for each dimensions during search
                for (int i = 0; i < colCount; i++) offsets[i] = -1;

                int top = -1; // The current level/top where we change the offset. Depth of recursion.
                do ++top; while (top < colCount && lengths[top] == 0);

                // Alternative recursive iteration: http://stackoverflow.com/questions/13655299/c-sharp-most-efficient-way-to-iterate-through-multiple-arrays-list
                while (top >= 0)
                {
                    if (top == colCount) // New element is ready. Process it.
                    {
                        // Initialize a record and append it
                        for (int i = 0; i < colCount; i++)
                        {
                            vals[i] = offsets[i];
                        }
                        Rowid input = tableWriter.Append(cols, vals);

                        //
                        // Now check if this appended element satisfies the where expression and if not then remove it
                        //
                        if (outputExpr != null)
                        {
                            // Set 'this' variable to the last elements (that has been just appended) which will be read by the expression
                            thisVariable.SetValue(this.GetData().Length - 1);

                            // Evaluate expression
                            outputExpr.Evaluate();

                            bool satisfies = (bool)outputExpr.OutputVariable.GetValue();

                            if (!satisfies)
                            {
                                Length = Length - 1; // Remove elements
                            }
                        }

                        top--;
                        while (top >= 0 && lengths[top] == 0) // Go up by skipping empty dimensions and reseting 
                        { offsets[top--] = -1; }
                    }
                    else
                    {
                        // Find the next valid offset
                        offsets[top]++;

                        if (offsets[top] < lengths[top]) // Offset chosen
                        {
                            do ++top;
                            while (top < colCount && lengths[top] == 0); // Go up (forward) by skipping empty dimensions
                        }
                        else // Level is finished. Go back.
                        {
                            do { offsets[top--] = -1; }
                            while (top >= 0 && lengths[top] == 0); // Go down (backward) by skipping empty dimensions and reseting 
                        }
                    }
                }

                // Prepare columns
                foreach (DcColumn col in cols)
                {
                    col.GetData().Reindex();
                    col.GetData().AutoIndex = true;
                }

                if (tableWriter != null)
                {
                    tableWriter.Close();
                }
                if (outputExpr != null)
                {
                    outputExpr.EvaluateEnd();
                }
            }
            else
            {
                throw new NotImplementedException("This table definition type is not implemented and cannot be populated.");
            }

        }
Пример #3
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.");
            }
        }