Пример #1
0
        public virtual Rowid Find(ExprNode expr) // Use only identity dims (for general case use Search which returns a subset of elements)
        {
            // Find the specified tuple but not its nested tuples (if nested tuples have to be found before then use recursive calls, say, a visitor or recursive epxression evaluation)

            Debug.Assert(!table.IsPrimitive, "Wrong use: cannot append to a primitive set. ");
            Debug.Assert(expr.OutputVariable.TypeTable == table, "Wrong use: expression OutputSet must be equal to the set its value is appended/found.");
            Debug.Assert(expr.Operation == OperationType.TUPLE, "Wrong use: operation type for appending has to be TUPLE. ");

            Rowid[] result            = Enumerable.Range(0, table.GetData().Length).ToArray(); // All elements of this set (can be quite long)
            bool    hasBeenRestricted = false;                                                 // For the case where the Length==1, and no key columns are really provided, so we get at the end result.Length==1 which is misleading. Also, this fixes the problem of having no key dimensions.

            List <DcColumn> dims = new List <DcColumn>();

            dims.AddRange(table.Columns.Where(x => x.IsKey));
            dims.AddRange(table.Columns.Where(x => !x.IsKey));

            foreach (DcColumn dim in dims) // OPTIMIZE: the order of dimensions matters (use statistics, first dimensins with better filtering). Also, first identity dimensions.
            {
                ExprNode childExpr = expr.GetChild(dim.Name);
                if (childExpr != null)
                {
                    object val = null;
                    val = childExpr.OutputVariable.GetValue();

                    hasBeenRestricted = true;
                    Rowid[] range = dim.GetData().Deproject(val); // Deproject the value
                    result = result.Intersect(range).ToArray();   // Intersect with previous de-projections
                    // OPTIMIZE: Write our own implementation for intersection and other operations. Assume that they are ordered.
                    // OPTIMIZE: Remember the position for the case this value will have to be inserted so we do not have again search for this positin during insertion (optimization)

                    if (result.Length == 0)
                    {
                        break;                     // Not found
                    }
                }
            }

            if (result.Length == 0) // Not found
            {
                return(-1);
            }
            else if (result.Length == 1) // Found single element - return its offset
            {
                if (hasBeenRestricted)
                {
                    return(result[0]);
                }
                else
                {
                    return(-result.Length);
                }
            }
            else // Many elements satisfy these properties (non-unique identities). Use other methods for getting these records (like de-projection)
            {
                return(-result.Length);
            }
        }
Пример #2
0
        public void SetColumns(ExprNode expr)
        {
            Columns       = new List <string>();
            ColumnIndexes = new Dictionary <string, int>();

            for (int i = 0; i < expr.Children.Count; i++)
            {
                ExprNode child = expr.GetChild(i);
                Columns.Add(child.Name);
                ColumnIndexes.Add(Columns[i], i);
            }
        }
Пример #3
0
        public virtual Rowid Append(ExprNode expr) // Identity dims must be set (for uniqueness). Entity dims are also used when appending.
        {
            // Append: append *this* tuple to the set
            // Greater tuples are not processed  - it is the task of the interpreter. If it is necessary to append (or do something else) with a greater tuple then it has to be done in the interpreter (depending on the operation, action and other parameters)
            // This method is intended for only appending one row while tuple is used only as a data structure (so its usage for interpretation is not used)
            // So this method expects that child nodes have been already evaluated and store the values in the result.
            // So this method is equivalent to appending using other row representations.
            // The offset of the appended element is stored as a result in this tuple and also returned.
            // If the tuple already exists then it is found and its current offset is returned.
            // It is assumed that child expressions represent dimensions.
            // It is assumed that the column names are resolved.

            Debug.Assert(!table.IsPrimitive, "Wrong use: cannot append to a primitive set. ");
            Debug.Assert(expr.OutputVariable.TypeTable == table, "Wrong use: expression OutputSet must be equal to the set its value is appended/found.");
            Debug.Assert(expr.Operation == OperationType.TUPLE, "Wrong use: operation type for appending has to be TUPLE. ");

            //
            // TODO: Check existence (uniqueness of the identity)
            //

            //
            // Really append a new element to the set
            //
            foreach (DcColumn dim in table.Columns)           // We must append one value to ALL greater dimensions (possibly null)
            {
                ExprNode childExpr = expr.GetChild(dim.Name); // TODO: replace by accessor by dimension reference (has to be resolved in the tuple)
                object   val       = null;
                if (childExpr != null)                        // A tuple contains a subset of all dimensions
                {
                    val = childExpr.OutputVariable.GetValue();
                }
                dim.GetData().Append(val);
            }

            //
            // TODO: Check other constraints (for example, where constraint). Remove if not satisfies and return status.
            //

            table.GetData().Length = table.GetData().Length + 1;
            return(table.GetData().Length - 1);
        }