예제 #1
0
        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()));
        }
예제 #2
0
        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();
        }
예제 #3
0
        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));
        }