IStatement IPreparableStatement.Prepare(IRequest request) { var tableName = request.Query.ResolveTableName(TableName); if (tableName == null) throw new ObjectNotFoundException(TableName); var columns = new string[0]; if (ColumnNames != null) columns = ColumnNames.ToArray(); ITableQueryInfo tableQueryInfo = request.Query.GetTableQueryInfo(tableName, null); var fromTable = new FromTableDirectSource(request.Query.IgnoreIdentifiersCase(), tableQueryInfo, "INSERT_TABLE", tableName, tableName); // Get the table we are inserting to var insertTable = request.Query.GetTable(tableName); if (columns.Length == 0) { columns = new string[insertTable.TableInfo.ColumnCount]; for (int i = 0; i < columns.Length; i++) { columns[i] = insertTable.TableInfo[i].ColumnName; } } var colIndices = new int[columns.Length]; var colResolved = new ObjectName[columns.Length]; for (int i = 0; i < columns.Length; ++i) { var inVar = new ObjectName(columns[i]); var col = ResolveColumn(fromTable, inVar); int index = insertTable.FindColumn(col); if (index == -1) throw new InvalidOperationException(String.Format("Cannot find column '{0}' in table '{1}'.", col, tableName)); colIndices[i] = index; colResolved[i] = col; } var queryPlan = request.Context.QueryPlanner().PlanQuery(new QueryInfo(request, QueryExpression)); return new Prepared(tableName, colResolved, colIndices, queryPlan); }
protected override SqlStatement PrepareStatement(IRequest context) { var values = Values.ToArray(); int firstLen = -1; for (int n = 0; n < values.Length; ++n) { var expList = (IList)values[n]; if (firstLen == -1 || firstLen == expList.Count) { firstLen = expList.Count; } else { throw new InvalidOperationException("The insert data list varies in size."); } } var tableName = context.Access().ResolveTableName(TableName); var table = context.Access().GetTable(tableName); if (table == null) throw new ObjectNotFoundException(TableName); if (Values.Any(x => x.OfType<SqlQueryExpression>().Any())) throw new InvalidOperationException("Cannot set a value from a query."); var tableQueryInfo = context.Access().GetTableQueryInfo(tableName, null); var fromTable = new FromTableDirectSource(context.Query.IgnoreIdentifiersCase(), tableQueryInfo, "INSERT_TABLE", tableName, tableName); var columns = new string[0]; if (ColumnNames != null) columns = ColumnNames.ToArray(); if (columns.Length == 0) { columns = new string[table.TableInfo.ColumnCount]; for (int i = 0; i < columns.Length; i++) { columns[i] = table.TableInfo[i].ColumnName; } } var colIndices = new int[columns.Length]; var colResolved = new ObjectName[columns.Length]; for (int i = 0; i < columns.Length; ++i) { var inVar = new ObjectName(columns[i]); var col = ResolveColumn(fromTable, inVar); int index = table.FindColumn(col); if (index == -1) throw new InvalidOperationException(String.Format("Cannot find column '{0}' in table '{1}'.", col, tableName)); colIndices[i] = index; colResolved[i] = col; } var columnInfos = new List<ColumnInfo>(); foreach (var name in columns) { var columnName = new ObjectName(tableName, name); var colIndex = table.FindColumn(columnName); if (colIndex < 0) throw new InvalidOperationException(String.Format("Cannot find column '{0}' in table '{1}'", columnName, table.TableInfo.TableName)); columnInfos.Add(table.TableInfo[colIndex]); } var assignments = new List<SqlAssignExpression[]>(); foreach (var valueSet in values) { var valueAssign = new SqlAssignExpression[valueSet.Length]; for (int i = 0; i < valueSet.Length; i++) { var columnInfo = columnInfos[i]; var value = valueSet[i]; if (value != null) { // TODO: Deference columns with a preparer } if (value != null) { var expReturnType = value.ReturnType(context, null); if (!expReturnType.Equals(columnInfo.ColumnType) && !expReturnType.CanCastTo(columnInfo.ColumnType)) { var sb = new StringBuilder (); sb.AppendFormat ("Unable to convert type {0} of {1} into type {2} of column {3}", expReturnType, value, columnInfo.ColumnType, columnInfo.FullColumnName.FullName); var ioe = new InvalidOperationException (sb.ToString()); throw ioe; } } valueAssign[i] = SqlExpression.Assign(SqlExpression.Reference(columnInfo.FullColumnName), value); } assignments.Add(valueAssign); } return new Prepared(tableName, assignments); }