Example #1
0
            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));
                }
            }
Example #2
0
        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)));
                }
            }
        }
Example #3
0
 private SqlExpression Expression(IExpressionNode node)
 {
     var visitor = new ExpressionBuilder();
     return visitor.Build(node);
 }
Example #4
0
        /// <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);
            }
        }