Пример #1
0
 public static SqlObject Concat(SqlObject[] args)
 {
     StringBuilder sb = new StringBuilder();
     for (int i = 0; i < args.Length; ++i) {
         sb.Append(args[i].Value.ToString());
     }
     return new SqlObject(sb.ToString());
 }
Пример #2
0
        public FunctionResultTable(SqlObject[] values)
        {
            this.values = values;

            columns = new ColumnCollection(this);
            for (int i = 0; i < values.Length; i++) {
                columns.Add(new TableColumn(this, "column" + i, values[i].Type));
            }
            columns.MakeReadOnly();
        }
Пример #3
0
 public static SqlObject And(SqlObject[] args)
 {
     if (IsBooleanType(args[0]) && IsBooleanType(args[1])) {
         bool? b1 = args[0].Value.ToBoolean();
         bool? b2 = args[1].Value.ToBoolean();
         return b1 == null || b2 == null ? SqlObject.MakeNull(SqlType.Boolean) : AsBooleanValue(b1.Value && b2.Value);
     }
     // Return null boolean,
     return SqlObject.MakeNull(SqlType.Boolean);
 }
        public ITable Evaluate(QueryProcessor processor, Expression[] args)
        {
            // 'CAST' is a special case,
            if (function.Name.Equals("@cast")) {
                // Get the value to cast, and the type to cast it to,
                SqlObject val = QueryProcessor.Result(processor.Execute(args[0]))[0];
                SqlObject castType = QueryProcessor.Result(processor.Execute(args[1]))[0];

                string castTypeString = castType.Value.ToString();
                SqlType type = SqlType.Parse(castTypeString);

                // Do the cast,
                SqlObject result = val.CastTo(type);

                // And return the result,
                return QueryProcessor.ResultTable(result);
            }

            if (function.IsAggregate)
                throw new InvalidOperationException("The function is aggregate.");

            try {
                // Execute it
                if (invokeType == 6) {
                    object[] funArgs = { function.Name, processor, args };
                    return (ITable)method.Invoke(null, funArgs);
                }
                    // The QueryProcessor, Expression[] construct
                if (invokeType == 1) {
                    object[] funArgs = { processor, args };
                    return (ITable)method.Invoke(null, funArgs);
                }
                    // The SqlObject construct
                if (invokeType == 2) {
                    int sz = args.Length;
                    // Resolve the arguments into TypedValues
                    SqlObject[] obs = new SqlObject[sz];
                    for (int i = 0; i < sz; ++i) {
                        obs[i] = QueryProcessor.Result(processor.Execute(args[i]))[0];
                    }
                    // Set up the arguments and invoke the method
                    object[] funArgs = { obs };
                    SqlObject result = (SqlObject)method.Invoke(null, funArgs);
                    // Wrap on a FunctionTable and return
                    return QueryProcessor.ResultTable(result);
                }

                throw new ApplicationException("Unknown invoke type");
            } catch (MethodAccessException e) {
                throw new ApplicationException(e.Message, e);
            } catch (TargetInvocationException e) {
                throw new ApplicationException(e.InnerException.Message, e.InnerException);
            }
        }
Пример #5
0
        public static SqlObject[] Result(ITable table)
        {
            if (!(table is FunctionResultTable))
                throw new ArgumentException("The table must be the result of a function execution.", "table");

            int cols = table.Columns.Count;
            SqlObject[] result = new SqlObject[cols];
            for (int i = 0; i < cols; ++i) {
                result[i] = table.GetValue(i, new RowId(0));
            }
            return result;
        }
Пример #6
0
 public override SqlObject[] GetValue(RowId rowid)
 {
     SqlObject[] values;
     if (columns.Length == 1) {
         // Single value
         values = new SqlObject[] { table.GetValue(columns[0], rowid) };
     } else {
         // Composite value so create a composite object as the key.
         int sz = columns.Length;
         values = new SqlObject[sz];
         for (int i = 0; i < sz; ++i) {
             values[i] = table.GetValue(columns[i], rowid);
         }
     }
     return values;
 }
Пример #7
0
 private ITable FetchStatic(SqlObject[] ob)
 {
     return ResultTable(ob);
 }
Пример #8
0
 public SqlObject Concat(SqlObject[] others)
 {
     SqlObject[] args = new SqlObject[others.Length + 1];
     args[0] = this;
     Array.Copy(others, 0, args, 1, others.Length);
     return SystemFunctions.Concat(args);
 }
Пример #9
0
 public FetchStaticExpression(SqlObject[] values)
     : base(ExpressionType.FetchStatic)
 {
     SetArgument("static", values);
 }
Пример #10
0
            public override SqlObject[] GetValue(RowId rowid)
            {
                // Set the top of stack table row_id
                processor.UpdateTableRow(rowid);
                if (columnExps.Length == 1)
                    // If a single part,
                    return Result(processor.DoExecute(columnExps[0]));

                // TODO: We can clean this up a great deal! We should make
                //   'DoExecute' produce a table with multiple columns when a
                //   composite function is given.
                int compParts = columnExps.Length;
                // If composite,
                SqlObject[] arr = new SqlObject[compParts];
                for (int i = 0; i < compParts; ++i)
                    arr[i] = Result(processor.DoExecute(columnExps[i]))[0];
                return arr;
            }
Пример #11
0
        internal void RemoveIndex(long index_id)
        {
            IIndexSetDataSource index = GetIndex(SystemTableNames.Index, "id_idx");
            SqlObject val = new SqlObject(index_id);
            // Query the index
            IRowCursor cursor = index.Select(SelectableRange.Is(val));
            // We assert this (we have already checked the index exists and this
            // iterator is valid).
            if (cursor.Count != 1)
                throw new ApplicationException();

            // The index table,
            IMutableTable indexTable = GetTable(SystemTableNames.Index);
            if (!cursor.MoveNext())
                throw new ApplicationException();

            RowId rowId = cursor.Current;
            indexTable.Delete(rowId);

            // Update indexes on index table
            IIndexSetDataSource[] idxs = GetTableIndexes(SystemTableNames.Index);
            foreach (IIndexSetDataSource idx in idxs) {
                idx.Remove(rowId);
            }
        }
Пример #12
0
        public void PerformSample(SystemTransaction transaction)
        {
            // Translate into tables and column names
            ITable tableSource = transaction.GetTable(var.TableName);
            // DOn't bother unless the table has 64 or more values
            if (tableSource.RowCount < (DivisionPointCount * 2)) {
                sampleCount = 0;
                totalSize = 0;
                return;
            }
            // The number of elements in total
            totalSize = tableSource.RowCount;
            // The actual number of samples,
            sampleCount = (int)System.Math.Min(tableSource.RowCount / 2, MaxSampleCount);

            String col_name = var.Name;
            int colId = tableSource.Columns.IndexOf(var.Name);
            // Work out the size
            long size = tableSource.RowCount;
            // The sample point difference
            double sampleDiff = (double)size / sampleCount;
            // The index of the tables used in sampling
            IIndex<RowId> sampleIndex = transaction.CreateTemporaryIndex<RowId>(sampleCount);
            // Create a RowIndexCollation for this
            SqlType type;
            type = tableSource.Columns[colId].Type;
            IndexCollation collation = new IndexCollation(type, col_name);
            // Create the collation object,
            CollationIndexResolver resolver = new CollationIndexResolver(tableSource, collation);

            // The row cursor
            IRowCursor rowCursor = tableSource.GetRowCursor();

            RowId[] sampleRowset = new RowId[sampleCount];

            // First read in the row_ids we are sampling,
            {
                // The current sample point
                double p = 0;
                // The number read,
                int samplesRead = 0;
                // Make a sorted sample index of the dataset
                while (samplesRead < sampleCount) {
                    long pos = ((long)p) - 1;
                    pos = System.Math.Min(pos, tableSource.RowCount - 2);
                    rowCursor.MoveTo(pos);
                    if (!rowCursor.MoveNext())
                        throw new SystemException();

                    RowId rowId = rowCursor.Current;
                    sampleRowset[samplesRead] = rowId;

                    // Should this be Math.random(sample_diff * 2) for random distribution
                    // of the samples?
                    p += sampleDiff;
                    ++samplesRead;
                }
            }

            // Now read the samples,
            {

                int samplePoint = 0;

                foreach (RowId rowId in sampleRowset) {
                    // Hint ahead the samples we are picking,
                    if ((samplePoint % 24) == 0) {
                        for (int i = samplePoint;
                             i < samplePoint + 24 && i < sampleRowset.Length;
                             ++i) {
                            tableSource.PrefetchValue(-1, sampleRowset[i]);
                        }
                    }

                    // Pick the sample and sort it,
                    SqlObject[] sample = new SqlObject[] { tableSource.GetValue(colId, rowId) };
                    sampleIndex.Insert(sample, rowId, resolver);

                    ++samplePoint;
                }
            }

            // Now extract the interesting sample points from the sorted set
            IIndexCursor<RowId> samplesCursor = sampleIndex.GetCursor();
            long sampleIndexSize = sampleIndex.Count;
            double divisionDiff = sampleIndexSize / (DivisionPointCount - 1);
            for (int i = 0; i < DivisionPointCount; ++i) {
                long samplePoint = (long)(divisionDiff * i);
                if (samplePoint >= sampleIndexSize) {
                    samplePoint = sampleIndexSize - 1;
                }

                samplesCursor.Position = samplePoint - 1;
                if (!samplesCursor.MoveNext())
                    throw new SystemException();

                RowId rowId = samplesCursor.Current;
                divisionPoints[i] = tableSource.GetValue(colId, rowId);
            }

            // Clear the temporary index
            sampleIndex.Clear();
        }
Пример #13
0
        private static void AutoCastSystemOperator(FunctionExpression exp, IList<Expression> parameters, List<SqlType> paramTypes)
        {
            SqlType t1 = paramTypes[0];
            SqlType t2 = paramTypes[1];

            // If both the types are identical, we good to go,
            if (!t1.IsComparableTo(t2))
                throw InvalidTypes(t1, t2, exp);

            // Types are compatible,
            // If they are numeric,

            if (t1.IsNumeric) {
                // The encoding is different, so now we do a static check
                if (!t1.Equals(t2)) {
                    // TODO: We should do a check on each parameter by walking the tree
                    //   to determine if it's static or not.

                    Expression exp1 = parameters[0];
                    Expression exp2 = parameters[1];

                    int staticop;
                    int varop;

                    // If the left or right is FETCHSTATIC,
                    if (exp1 is FetchStaticExpression) {
                        staticop = 0;
                        varop = 1;
                    } else if (exp2 is FetchStaticExpression) {
                        staticop = 1;
                        varop = 0;
                    } else {
                        // Neither static, so report error,
                        throw InvalidTypes(t1, t2, exp);
                    }

                    // The type of the variable and static sides,
                    SqlType varType = paramTypes[varop];

                    SqlObject castType = new SqlObject(varType.ToString());
                    FetchStaticExpression castExp = new FetchStaticExpression(castType);
                    castExp.ReturnType = SqlType.GetSqlType(typeof(string));

                    // Cast the static type to the variable type,
                    FunctionExpression newStaticExp = new FunctionExpression("@cast", new Expression[] {parameters[staticop], castExp});
                    newStaticExp.ReturnType = varType;
                    exp.Parameters[staticop] = newStaticExp;

                }
            }
        }
Пример #14
0
 public SqlObject Or(SqlObject other)
 {
     return SystemFunctions.Or(new SqlObject[]{this, other});
 }
Пример #15
0
            public override void SetValue(int columnOffset, SqlObject value)
            {
                if (query == null)
                    throw new InvalidOperationException("The backed query is null.");

                if (columnOffset >= query.Parameters.Count) {
                    for (int i = query.Parameters.Count - 1; i < columnOffset; i++) {
                        query.Parameters.Add(SqlObject.Null);
                    }
                }

                query.Parameters[columnOffset].Value = value;
            }
Пример #16
0
 public SqlObject LesserThan(SqlObject other)
 {
     return SystemFunctions.LesserThan(new SqlObject[] {this, other});
 }
Пример #17
0
 public SqlObject IsNot(SqlObject other)
 {
     return SystemFunctions.IsNot(new SqlObject[] {this, other});
 }
Пример #18
0
 public SqlObject GreaterOrEqualThan(SqlObject other)
 {
     return SystemFunctions.GreaterOrEqualThan(new SqlObject[] { this, other });
 }
Пример #19
0
 public static FunctionResultTable ResultTable(SqlObject[] val)
 {
     return new FunctionResultTable(val);
 }
Пример #20
0
        public virtual void SetValue(int columnOffset, SqlObject value)
        {
            CheckMutable();

            if (columnOffset < 0 || columnOffset >= table.Columns.Count)
                throw new ArgumentOutOfRangeException("columnOffset");

            TableColumn column = table.Columns[columnOffset];

            if (value == null) {
                value = SqlObject.MakeNull(column.Type);
            } else if (!column.Type.Equals(value.Type)) {
                value = value.CastTo(column.Type);
            }

            cachedValues[columnOffset] = value;
            dirty = true;
        }
Пример #21
0
            public override int Compare(RowId rowid, SqlObject[] value)
            {
                SqlObject[] val1 = GetValue(rowid);
                SqlObject[] val2 = value;

                // Compare until we reach the end of the array.
                int min_compare = System.Math.Min(val1.Length, val2.Length);
                for (int i = 0; i < min_compare; ++i) {
                    int c = SqlObject.Compare(val1[i], val2[i]);
                    if (c != 0) {
                        bool rev = ascending[i];
                        return rev ? c : -c;
                    }
                }

                // If the sizes are equal, compare equally,
                if (val1.Length == val2.Length)
                    return 0;

                // If val1.length is greater, return +1, else return -1 (val1.length is
                // less)
                if (val1.Length > val2.Length) {
                    return 1;
                } else {
                    return -1;
                }
            }
Пример #22
0
 private ITable FilterByIndex(ITable table, IIndexSetDataSource index, Expression order, string compareFunction, SqlObject[] values)
 {
     // Make a selectable range set
     SelectableRange range = SelectableRange.Full;
     range = range.Intersect(SelectableRange.GetOperatorFromFunction(compareFunction), values);
     // And return the subset
     return FilterByIndex(table, index, order, range);
 }
Пример #23
0
 public static FunctionResultTable ResultTable(SqlObject val)
 {
     return new FunctionResultTable(new SqlObject[] { val });
 }
Пример #24
0
 public FetchStaticExpression(SqlObject value)
     : this(new SqlObject[] { value })
 {
 }
Пример #25
0
                public override void SetValue(int columnOffset, SqlObject value)
                {
                    if (columnOffset == 0) {
                        queryString = value;
                    } else {
                        if (columnOffset >= table.Columns.Count) {
                            int toAdd = columnOffset - table.Columns.Count - 1;
                            for (int i = 0; i < toAdd; i++)
                                table.Columns.Add("#PARAM" + (table.Columns.Count - 1), SqlType.Null, false);

                            table.Columns.Add("#PARAM" + (table.Columns.Count - 1), value.Type, false);
                        }

                        columnOffset = columnOffset - 1;
                        if (columnOffset >= values.Count) {
                            int toAdd = columnOffset - values.Count;
                            for (int i = 0; i < toAdd; i++)
                                values.Add(SqlObject.Null);

                            values.Add(SqlObject.Null);
                        }

                        values[columnOffset] = value;
                    }
                }
Пример #26
0
 public SqlObject Concat(SqlObject other)
 {
     return Concat(new SqlObject[] { other});
 }
Пример #27
0
        public void SetValue(string columnName, SqlObject value)
        {
            if (String.IsNullOrEmpty(columnName))
                throw new ArgumentNullException("columnName");

            SetValue(GetColumnOffset(columnName), value);
        }
Пример #28
0
        private static SqlObject CreateValue(ITable table, RowId rowid, IList<string> columns)
        {
            int sz = columns.Count;
            if (sz == 0)
                throw new ArgumentException();

            // If there's just 1 column reference, we fetch the TObject and return
            // it.
            if (sz == 1) {
                string columnName = columns[0];
                int columnOffset = table.Columns.IndexOf(columnName);
                return table.GetValue(columnOffset, rowid);
            }

            // Otherwise we make a composite object

            // Make the composite type
            SqlObject[] val = new SqlObject[sz];
            for (int i = 0; i < sz; ++i) {
                int columnOffset = table.Columns.IndexOf(columns[i]);
                val[i] = table.GetValue(columnOffset, rowid);
            }
            // Create the composite type and return the object
            return SqlObject.MakeComposite(val);
        }
Пример #29
0
 private ITable FilterByIndex(ITable table, IIndexSetDataSource index, Expression order, string compareFunction, SqlObject value)
 {
     return FilterByIndex(table, index, order, compareFunction, new SqlObject[] { value });
 }
Пример #30
0
        private static IRowCursor QueryAllMatches(SystemTransaction transaction, TableName tableName, SystemTable table,
            IList<string> columns, SqlObject val)
        {
            // Try and find an index on these columns
            SystemIndexSetDataSource indexSet = transaction.FindIndexOn(tableName, columns);

            // If index found
            if (indexSet != null)
                // Query the index and find all matches
                return indexSet.Select(SelectableRange.Is(val));

            // Otherwise no index, so scan the table for matches

            // Make an Expression for the operation;
            //  (column1, column2, ...columnn) = val
            Expression compExp;
            int sz = columns.Count;
            if (sz > 1) {
                FunctionExpression cfunExp = new FunctionExpression("composite_fetch");
                for (int i = 0; i < sz; ++i) {
                    Expression varRef = new FetchVariableExpression(new Variable(tableName, columns[i]));
                    cfunExp.Parameters.Add(varRef);
                }
                compExp = cfunExp;
            } else if (sz == 1) {
                compExp = new FetchVariableExpression(new Variable(tableName, columns[0]));
            } else {
                throw new ApplicationException("Invalid columns list size");
            }

            // Equality test
            FunctionExpression funExp = new FunctionExpression("@is_sql");
            funExp.Parameters.Add(compExp);
            funExp.Parameters.Add(new FetchStaticExpression(val));

            // Create a query processor and perform the scan operation
            QueryProcessor processor = new QueryProcessor(transaction);
            ITable result = processor.FilterByScan(table, funExp);
            // Return the row cursor
            return result.GetRowCursor();
        }