public static void Build(IQueryContext context, CreateTableNode node, ICollection<SqlStatement> statements) { string idColumn = null; var dataTypeBuilder = new DataTypeBuilder(); var tableName = node.TableName; var objTableName = ObjectName.Parse(tableName.Name); var constraints = new List<ConstraintInfo>(); var columns = new List<SqlTableColumn>(); var expBuilder = new ExpressionBuilder(); foreach (var column in node.Columns) { var dataType = dataTypeBuilder.Build(context.TypeResolver(), column.DataType); var columnInfo = new SqlTableColumn(column.ColumnName.Text, dataType); if (column.Default != null) columnInfo.DefaultExpression = expBuilder.Build(column.Default); if (column.IsIdentity) { if (!String.IsNullOrEmpty(idColumn)) throw new InvalidOperationException(String.Format("Table {0} defines already {1} as identity column.", node.TableName, idColumn)); if (column.Default != null) throw new InvalidOperationException(String.Format("The identity column {0} cannot have a DEFAULT constraint.", idColumn)); idColumn = column.ColumnName.Text; columnInfo.DefaultExpression = SqlExpression.FunctionCall("UNIQUEKEY", new[] {SqlExpression.Constant(node.TableName.Name)}); } foreach (var constraint in column.Constraints) { if (String.Equals(ConstraintTypeNames.Check, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { var exp = expBuilder.Build(constraint.CheckExpression); constraints.Add(ConstraintInfo.Check(objTableName, exp, column.ColumnName.Text)); } else if (String.Equals(ConstraintTypeNames.ForeignKey, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { var fTable = ObjectName.Parse(constraint.ReferencedTable.Name); var fColumn = constraint.ReferencedColumn.Text; var fkey = ConstraintInfo.ForeignKey(objTableName, column.ColumnName.Text, fTable, fColumn); if (!String.IsNullOrEmpty(constraint.OnDeleteAction)) fkey.OnDelete = GetForeignKeyAction(constraint.OnDeleteAction); if (!String.IsNullOrEmpty(constraint.OnUpdateAction)) fkey.OnUpdate = GetForeignKeyAction(constraint.OnUpdateAction); constraints.Add(fkey); } else if (String.Equals(ConstraintTypeNames.PrimaryKey, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { constraints.Add(ConstraintInfo.PrimaryKey(objTableName, column.ColumnName.Text)); } else if (String.Equals(ConstraintTypeNames.UniqueKey, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { constraints.Add(ConstraintInfo.Unique(objTableName, column.ColumnName.Text)); } else if (String.Equals(ConstraintTypeNames.NotNull, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { columnInfo.IsNotNull = true; } else if (String.Equals(ConstraintTypeNames.Null, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { columnInfo.IsNotNull = false; } } columns.Add(columnInfo); } foreach (var constraint in node.Constraints) { if (String.Equals(ConstraintTypeNames.Check, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { var exp = expBuilder.Build(constraint.CheckExpression); constraints.Add(ConstraintInfo.Check(constraint.ConstraintName, objTableName, exp, constraint.Columns.ToArray())); } else if (String.Equals(ConstraintTypeNames.PrimaryKey, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { constraints.Add(ConstraintInfo.PrimaryKey(constraint.ConstraintName, objTableName, constraint.Columns.ToArray())); } else if (String.Equals(ConstraintTypeNames.UniqueKey, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { constraints.Add(ConstraintInfo.Unique(constraint.ConstraintName, objTableName, constraint.Columns.ToArray())); } else if (String.Equals(ConstraintTypeNames.ForeignKey, constraint.ConstraintType, StringComparison.OrdinalIgnoreCase)) { var fTable = ObjectName.Parse(constraint.ReferencedTableName.Name); var fColumns = constraint.ReferencedColumns; var fkey = ConstraintInfo.ForeignKey(constraint.ConstraintName, objTableName, constraint.Columns.ToArray(), fTable, fColumns.ToArray()); if (!String.IsNullOrEmpty(constraint.OnDeleteAction)) fkey.OnDelete = GetForeignKeyAction(constraint.OnDeleteAction); if (!String.IsNullOrEmpty(constraint.OnUpdateAction)) fkey.OnUpdate = GetForeignKeyAction(constraint.OnUpdateAction); constraints.Add(fkey); } } //TODO: Optimization: merge same constraints statements.Add(MakeCreateTable(tableName.Name, columns, node.IfNotExists, node.Temporary)); foreach (var constraint in constraints) { statements.Add(MakeAlterTableAddConstraint(tableName.Name, constraint)); } }