public static ITable If(QueryProcessor processor, Expression[] args) { SqlObject[] conditional = QueryProcessor.Result(processor.Execute(args[0])); // If it evaluated to true, bool? b = conditional[0].Value.ToBoolean(); return b != null && b == true ? processor.Execute(args[1]) : processor.Execute(args[2]); }
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 ITable GroupConcat(QueryProcessor processor, bool distinct, ITable group, Expression[] args) { // The output string StringBuilder return_string = new StringBuilder(); // Find the distinct subset of group if (distinct) group = processor.DistinctSubset(group, args); // Push the group table onto the processor stack processor.PushTable(group); // Iterator over the group IRowCursor i = group.GetRowCursor(); bool first = true; while (i.MoveNext()) { RowId rowid = i.Current; processor.UpdateTableRow(rowid); foreach (Expression op in args) { ITable val = processor.Execute(op); SqlObject ob = QueryProcessor.Result(val)[0]; if (!ob.IsNull) { if (!first) { return_string.Append(", "); } return_string.Append(SqlValue.FromObject(ob.Value).ToString()); first = false; } } } // Pop the table and return the result processor.PopTable(); return QueryProcessor.ResultTable(new SqlObject(return_string.ToString())); }
public static ITable Least(QueryProcessor processor, Expression[] args) { SqlObject least = null; for (int i = 0; i < args.Length; ++i) { SqlObject ob = QueryProcessor.Result(processor.Execute(args[i]))[0]; if (ob.IsNull) return QueryProcessor.ResultTable(ob); if (least == null || SqlObject.Compare(ob, least) < 0) least = ob; } return QueryProcessor.ResultTable(least); }
internal static void SetInsertRowToDefault(SystemTransaction transaction, TableName table_name, IMutableTable table, RowId rowid) { // Get all column defaults on the table IList<object> table_defaults = transaction.QueryTableDefaults(table_name); int sz = table_defaults.Count / 2; // Exit quickly if there's no default values if (sz == 0) return; // Create a query processor QueryProcessor processor = new QueryProcessor(transaction); // For each default value, TableRow row = table.GetRow(rowid); for (int i = 0; i < sz; ++i) { string colName = (string)table_defaults[i * 2]; Expression colDefault = (Expression)table_defaults[(i * 2) + 1]; // Execute the default value expression ITable defaultResult = processor.Execute(colDefault); // Turn it into a TObject SqlObject val = defaultResult.GetValue(0, new RowId(0)); // The col num of the column name int colIndex = table.Columns.IndexOf(colName); if (colIndex < 0) throw new ApplicationException("Column '" + colName + "' not found for DEFAULT value"); // And insert it row.SetValue(colIndex, val); } }
public ITable Execute(Query query, Expression expression) { // Create the QueryProcessor QueryProcessor processor = new QueryProcessor(transaction); // If it's a select, if (expression is SelectExpression) { QueryOptimizer optimizer = new QueryOptimizer(transaction); expression = optimizer.SubstituteParameters(expression, query); expression = optimizer.Qualify(expression); expression = optimizer.Optimize(expression); // Execute the query, return processor.Execute(expression); } // Set the parameter as the base table, and the base rowid (the // parameters table only has 1 row). processor.PushTable(new QueryParametersTable(query)); processor.UpdateTableRow(new RowId(0)); // Otherwise it must be an interpretable function if (expression is FunctionExpression) { string fun_name = (string)expression.GetArgument("name"); if (fun_name.Equals("create_table")) return CreateTable(expression); /* TODO: if (fun_name.Equals("drop_table")) return DropTable(processor, expression); if (fun_name.Equals("create_index")) return CreateIndex(processor, expression); if (fun_name.Equals("drop_index")) return DropIndex(processor, expression); if (fun_name.Equals("explain_expression")) return ExplainExpression(expression); */ } throw new NotSupportedException(); }
private static ITable ProcessAggregate(QueryProcessor processor, bool distinct, ITable group, Expression[] args, IAggregateInspector aggregator) { // Qualify the return type of the parameter SqlType type = processor.GetExpressionType(group, args[0]); // If an empty group if (group.RowCount == 0) { // Null return type if group is empty, return QueryProcessor.ResultTable(SqlObject.MakeNull(type)); } // Find the distinct subset of group if (distinct) group = processor.DistinctSubset(group, args); // Push the group table onto the processor stack processor.PushTable(group); // Scan the group table, returning null on a null value IRowCursor i = group.GetRowCursor(); while (i.MoveNext()) { RowId rowid = i.Current; processor.UpdateTableRow(rowid); ITable val = processor.Execute(args[0]); SqlObject ob = QueryProcessor.Result(val)[0]; // If we hit a null value, we ignore it. SQL-92 apparently says we // should generate a warning for nulls that are eliminated by set // functions. if (!ob.IsNull) { aggregator.Accumulate(ob); } } // Pop the table and return the result processor.PopTable(); SqlObject result = aggregator.Result(); return QueryProcessor.ResultTable(result ?? SqlObject.MakeNull(type)); }
private static ITable NestedAnyScan(QueryProcessor processor, Expression leftExp, Expression rightExp, NestedEvaluate evaluate) { // Evaluate the left and right side of the operation ITable left = processor.Execute(leftExp); ITable right = processor.Execute(rightExp); // Turn left into a SqlObject SqlObject leftOb = QueryProcessor.Result(left)[0]; // Scan right, return true on the first that's equal IRowCursor i = right.GetRowCursor(); try { while (i.MoveNext()) { RowId rowid = i.Current; SqlObject scanVal = right.GetValue(0, rowid); SqlObject[] args = new SqlObject[] { leftOb, scanVal }; SqlObject r = evaluate(args); if (Equals(r, new SqlObject(true))) { return QueryProcessor.ResultTable(new SqlObject(true)); } } } catch (AccessViolationException e) { throw new ApplicationException(e.Message, e); } catch (TargetInvocationException e) { throw new ApplicationException(e.InnerException.Message, e.InnerException); } return QueryProcessor.ResultTable(new SqlObject(false)); }
public static ITable Exists(QueryProcessor processor, Expression[] args) { // The nested expression to evaluate Expression nested_op = args[0]; // Execute the nested operation, ITable result = processor.Execute(nested_op); // If there are elements, then 'exists' is true return QueryProcessor.ResultTable(result.RowCount > 0 ? SqlObject.True : SqlObject.False); }
public static ITable Length(QueryProcessor processor, Expression[] args) { if (args.Length != 1) throw new ArgumentException("The function LENGTH accepts only 1 argument."); Expression arg = args[0]; SqlObject resultLength; SqlObject obj = QueryProcessor.Result(processor.Execute(arg))[0]; if (obj.IsNull) { resultLength = SqlObject.MakeNull(SqlType.Numeric); } else { int length; SqlType obType = obj.Type; SqlValue obValue = obj.Value; // If it's a string, if (obType.IsString) { length = obValue.ToString().Length; } // If it's a binary, else if (obType.IsBinary) { length = obValue.Length - 1; } // Otherwise, return null, else { length = -1; } resultLength = length == -1 ? SqlObject.MakeNull(SqlType.Numeric) : new SqlObject((long) length); } return QueryProcessor.ResultTable(resultLength); }