protected override SqlPreparedStatement PrepareStatement(IExpressionPreparer preparer, IQueryContext context) { var tableName = context.ResolveTableName(TableName); if (!context.TableExists(tableName)) throw new ObjectNotFoundException(tableName); var queryExpression = new SqlQueryExpression(new[]{SelectColumn.Glob("*") }); queryExpression.FromClause.AddTable(tableName.FullName); queryExpression.WhereExpression = WherExpression; var queryFrom = QueryExpressionFrom.Create(context, queryExpression); var queryPlan = context.DatabaseContext().QueryPlanner().PlanQuery(context, queryExpression, null); var columns = new List<SqlAssignExpression>(); foreach (var assignment in Assignments) { var columnName = ObjectName.Parse(assignment.ColumnName); var refName = queryFrom.ResolveReference(columnName); var expression = assignment.Expression.Prepare(queryFrom.ExpressionPreparer); var assign = SqlExpression.Assign(SqlExpression.Reference(refName), expression); columns.Add(assign); } return new Prepared(tableName, queryPlan, columns.ToArray(), Limit); }
public FunctionTable(ITable table, SqlExpression[] functionList, string[] columnNames, IQueryContext queryContext) : base(queryContext.DatabaseContext()) { // Make sure we are synchronized over the class. lock (typeof(FunctionTable)) { uniqueId = uniqueKeySeq; ++uniqueKeySeq; } uniqueId = (uniqueId & 0x0FFFFFFF) | 0x010000000; context = queryContext; ReferenceTable = table; varResolver = table.GetVariableResolver(); varResolver = varResolver.ForRow(0); // Create a DataTableInfo object for this function table. funTableInfo = new TableInfo(FunctionTableName); expList = new SqlExpression[functionList.Length]; expInfo = new byte[functionList.Length]; // Create a new DataColumnInfo for each expression, and work out if the // expression is simple or not. for (int i = 0; i < functionList.Length; ++i) { var expr = functionList[i]; // Examine the expression and determine if it is simple or not if (expr.IsConstant() && !expr.HasAggregate(context)) { // If expression is a constant, solve it var result = expr.Evaluate(context, null); if (result.ExpressionType != SqlExpressionType.Constant) throw new InvalidOperationException(); expr = result; expList[i] = expr; expInfo[i] = 1; } else { // Otherwise must be dynamic expList[i] = expr; expInfo[i] = 0; } // Make the column info funTableInfo.AddColumn(columnNames[i], expr.ReturnType(context, varResolver)); } // Make sure the table info isn't changed from this point on. funTableInfo = funTableInfo.AsReadOnly(); // routine tables are the size of the referring table. rowCount = table.RowCount; // Set schemes to 'blind search'. SetupIndexes(DefaultIndexTypes.BlindSearch); }
protected override SqlPreparedStatement PrepareStatement(IExpressionPreparer preparer, IQueryContext context) { var viewName = context.ResolveTableName(ViewName); var queryFrom = QueryExpressionFrom.Create(context, QueryExpression); var queryPlan = context.DatabaseContext().QueryPlanner().PlanQuery(context, QueryExpression, null); var colList = ColumnNames == null ? new string[0] : ColumnNames.ToArray(); // Wrap the result around a SubsetNode to alias the columns in the // table correctly for this view. int sz = colList.Length; var originalNames = queryFrom.GetResolvedColumns(); var newColumnNames = new ObjectName[originalNames.Length]; if (sz > 0) { if (sz != originalNames.Length) throw new InvalidOperationException("Column list is not the same size as the columns selected."); for (int i = 0; i < sz; ++i) { var colName = colList[i]; newColumnNames[i] = new ObjectName(viewName, colName); } } else { sz = originalNames.Length; for (int i = 0; i < sz; ++i) { newColumnNames[i] = new ObjectName(viewName, originalNames[i].Name); } } // Check there are no repeat column names in the table. for (int i = 0; i < sz; ++i) { var columnName = newColumnNames[i]; for (int n = i + 1; n < sz; ++n) { if (newColumnNames[n].Equals(columnName)) throw new InvalidOperationException(String.Format("Duplicate column name '{0}' in view. A view may not contain duplicate column names.", columnName)); } } // Wrap the plan around a SubsetNode plan queryPlan = new SubsetNode(queryPlan, originalNames, newColumnNames); // We have to execute the plan to get the TableInfo that represents the // result of the view execution. var table = queryPlan.Evaluate(context); var tableInfo = table.TableInfo.Alias(viewName); return new Prepared(tableInfo, QueryExpression, queryPlan, ReplaceIfExists); }
protected override SqlPreparedStatement PrepareStatement(IExpressionPreparer preparer, IQueryContext context) { var queryPlan = context.DatabaseContext().QueryPlanner().PlanQuery(context, QueryExpression, null); if (IsObjectReference) { var tableRef = ((SqlReferenceExpression) Reference).ReferenceName; var table = context.GetMutableTable(tableRef); if (table == null) throw new StatementPrepareException(String.Format("Referenced table of the INTO statement '{0}' was not found or is not mutable.", tableRef)); return new Prepared(queryPlan, table); } if (IsVariableReference) { throw new NotImplementedException(); } // Other (impossible) case... throw new NotSupportedException(); }
protected override SqlStatement PrepareStatement(IExpressionPreparer preparer, IQueryContext context) { var queryPlan = context.DatabaseContext().QueryPlanner().PlanQuery(context, QueryExpression, OrderBy); return new Prepared(queryPlan); }
private ITable Evaluate(IQueryContext context, SqlExpression[] args) { try { var prepared = PrepareQuery(args); var queryPlan = context.DatabaseContext().QueryPlanner().PlanQuery(context, prepared, null); return queryPlan.Evaluate(context); } catch (Exception) { throw; } }