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()); }
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(); }
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); } }
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; }
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; }
private ITable FetchStatic(SqlObject[] ob) { return ResultTable(ob); }
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); }
public FetchStaticExpression(SqlObject[] values) : base(ExpressionType.FetchStatic) { SetArgument("static", values); }
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; }
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); } }
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(); }
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; } } }
public SqlObject Or(SqlObject other) { return SystemFunctions.Or(new SqlObject[]{this, other}); }
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; }
public SqlObject LesserThan(SqlObject other) { return SystemFunctions.LesserThan(new SqlObject[] {this, other}); }
public SqlObject IsNot(SqlObject other) { return SystemFunctions.IsNot(new SqlObject[] {this, other}); }
public SqlObject GreaterOrEqualThan(SqlObject other) { return SystemFunctions.GreaterOrEqualThan(new SqlObject[] { this, other }); }
public static FunctionResultTable ResultTable(SqlObject[] val) { return new FunctionResultTable(val); }
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; }
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; } }
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); }
public static FunctionResultTable ResultTable(SqlObject val) { return new FunctionResultTable(new SqlObject[] { val }); }
public FetchStaticExpression(SqlObject value) : this(new SqlObject[] { value }) { }
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; } }
public SqlObject Concat(SqlObject other) { return Concat(new SqlObject[] { other}); }
public void SetValue(string columnName, SqlObject value) { if (String.IsNullOrEmpty(columnName)) throw new ArgumentNullException("columnName"); SetValue(GetColumnOffset(columnName), value); }
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); }
private ITable FilterByIndex(ITable table, IIndexSetDataSource index, Expression order, string compareFunction, SqlObject value) { return FilterByIndex(table, index, order, compareFunction, new SqlObject[] { value }); }
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(); }