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)); } }
private static void BuildAction(ITypeResolver typeResolver, ObjectName tableName, IAlterActionNode action, SqlCodeObjectBuilder builder) { if (action is AddColumnNode) { var column = ((AddColumnNode)action).Column; var constraints = new List <SqlTableConstraint>(); var columnInfo = column.BuildColumn(typeResolver, tableName.FullName, constraints); builder.AddObject(new AlterTableStatement(tableName, new AddColumnAction(columnInfo))); foreach (var constraint in constraints) { builder.AddObject(new AlterTableStatement(tableName, new AddConstraintAction(constraint))); } } else if (action is AddConstraintNode) { var constraint = ((AddConstraintNode)action).Constraint; var constraintInfo = constraint.BuildConstraint(); builder.AddObject(new AlterTableStatement(tableName, new AddConstraintAction(constraintInfo))); } else if (action is DropColumnNode) { var columnName = ((DropColumnNode)action).ColumnName; builder.AddObject(new AlterTableStatement(tableName, new DropColumnAction(columnName))); } else if (action is DropConstraintNode) { var constraintName = ((DropConstraintNode)action).ConstraintName; builder.AddObject(new AlterTableStatement(tableName, new DropConstraintAction(constraintName))); } else if (action is SetDefaultNode) { var actionNode = ((SetDefaultNode)action); var columnName = actionNode.ColumnName; var expression = ExpressionBuilder.Build(actionNode.Expression); builder.AddObject(new AlterTableStatement(tableName, new SetDefaultAction(columnName, expression))); } else if (action is DropDefaultNode) { var columnName = ((DropDefaultNode)action).ColumnName; builder.AddObject(new AlterTableStatement(tableName, new DropDefaultAction(columnName))); } else if (action is AlterColumnNode) { var column = ((AlterColumnNode)action).Column; var constraints = new List <SqlTableConstraint>(); var columnInfo = column.BuildColumn(typeResolver, tableName.FullName, constraints); // CHECK: Here we do a drop and add column: is there a better way on the back-end? builder.AddObject(new AlterTableStatement(tableName, new DropColumnAction(columnInfo.ColumnName))); builder.AddObject(new AlterTableStatement(tableName, new AddColumnAction(columnInfo))); foreach (var constraint in constraints) { builder.AddObject(new AlterTableStatement(tableName, new AddConstraintAction(constraint))); } } }
private SqlExpression Expression(IExpressionNode node) { var visitor = new ExpressionBuilder(); return visitor.Build(node); }
/// <summary> /// Parses the given SQL string to an expression that can be evaluated. /// </summary> /// <param name="s">The string to parse.</param> /// <param name="context"></param> /// <returns> /// Returns an instance of <seealso cref="SqlExpression"/> that represents /// the given SQL string parsed. /// </returns> public static SqlExpression Parse(string s, ISystemContext context) { try { // TODO: Get the expression compiler from the context var compiler = SqlParsers.Expression; var result = compiler.Parse(s); if (result.HasErrors) throw new SqlParseException(); var visitor = new ExpressionBuilder(); return visitor.Build(result.RootNode); } catch (SqlParseException ex) { throw new SqlExpressionException(ExpressionErrorCodes.CannotParse, "Could not parse input expression: see inner exception for details.", ex); } }