/// <summary> /// Parses CREATE INDEX statement. /// </summary> public static void Parse(PgDatabase database, string statement) { var parser = new Parser(statement); parser.Expect("CREATE"); var unique = parser.ExpectOptional("UNIQUE"); parser.Expect("INDEX"); parser.ExpectOptional("CONCURRENTLY"); var indexName = ParserUtils.GetObjectName(parser.ParseIdentifier()); parser.Expect("ON"); var tableName = parser.ParseIdentifier(); var definition = parser.Rest(); var schemaName = ParserUtils.GetSchemaName(tableName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new TeamworkParserException($"CannotFindSchema {schemaName} from {statement}"); } var objectName = ParserUtils.GetObjectName(tableName); PgTable table = schema.GetTable(objectName); if (table == null) { throw new TeamworkParserException($"CannotFindTable {tableName} from {statement}"); } var index = new PgIndex(indexName); table.AddIndex(index); schema.Add(index); index.Definition = definition.Trim(); index.TableName = table.Name; index.Unique = unique; }
/// <summary> /// Parses CREATE VIEW statement. /// </summary> public static void Parse(PgDatabase database, string statement) { var parser = new Parser(statement); parser.Expect("CREATE"); parser.ExpectOptional("OR", "REPLACE"); parser.Expect("VIEW"); var viewName = parser.ParseIdentifier(); var columnsExist = parser.ExpectOptional("("); var columnNames = new List <string>(10); if (columnsExist) { while (!parser.ExpectOptional(")")) { columnNames.Add(ParserUtils.GetObjectName(parser.ParseIdentifier())); parser.ExpectOptional(","); } } parser.ExpectOptional("WITH", "(security_barrier='false')"); parser.Expect("AS"); var query = parser.Rest(); var view = new PgView(ParserUtils.GetObjectName(viewName)) { ColumnNames = columnNames, Query = query, }; var schemaName = ParserUtils.GetSchemaName(viewName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new TeamworkParserException($"CannotFindSchema {schemaName} {statement}"); } schema.Add(view); }
/// <summary> /// Parses ADD CONSTRAINT action. /// </summary> private static void ParseAddConstraint(Parser parser, PgTable table, PgSchema schema) { var constraintName = ParserUtils.GetObjectName(parser.ParseIdentifier()); var constraint = new PgConstraint(constraintName) { TableName = table.Name, }; table.AddConstraint(constraint); if (parser.ExpectOptional("PRIMARY", "KEY")) { schema.Add(constraint); constraint.Definition = "PRIMARY KEY " + parser.Expression(); } else { constraint.Definition = parser.Expression(); } }
/// <summary> /// Parses CREATE FUNCTION and CREATE OR REPLACE FUNCTION statement. /// </summary> public static void Parse(PgDatabase database, string statement) { var parser = new Parser(statement); parser.Expect("CREATE"); parser.ExpectOptional("OR", "REPLACE"); parser.Expect("FUNCTION"); var functionName = parser.ParseIdentifier(); var schemaName = ParserUtils.GetSchemaName(functionName, database); PgSchema schema = database.GetSchema(schemaName); if (database.SchemaIsIgnored(schemaName)) { return; } if (schema == null) { throw new TeamworkParserException($"CannotFindSchema {schemaName} {statement}"); } var function = new PgFunction() { Name = ParserUtils.GetObjectName(functionName), }; schema.Add(function); parser.Expect("("); while (!parser.ExpectOptional(")")) { string mode; if (parser.ExpectOptional("IN")) { mode = "IN"; } else if (parser.ExpectOptional("OUT")) { mode = "OUT"; } else if (parser.ExpectOptional("INOUT")) { mode = "INOUT"; } else if (parser.ExpectOptional("VARIADIC")) { mode = "VARIADIC"; } else { mode = null; } var position = parser.Position; string argumentName = null; var dataType = parser.ParseDataType(); var position2 = parser.Position; if (!parser.ExpectOptional(")") && !parser.ExpectOptional(",") && !parser.ExpectOptional("=") && !parser.ExpectOptional("DEFAULT")) { parser.Position = position; argumentName = ParserUtils.GetObjectName(parser.ParseIdentifier()); dataType = parser.ParseDataType(); } else { parser.Position = position2; } string defaultExpression; if (parser.ExpectOptional("=") || parser.ExpectOptional("DEFAULT")) { defaultExpression = parser.Expression(); } else { defaultExpression = null; } var argument = new PgFunction.Argument() { DataType = dataType, DefaultExpression = defaultExpression, Mode = mode, Name = argumentName, }; function.AddArgument(argument); if (parser.ExpectOptional(")")) { break; } else { parser.Expect(","); } } function.Body = parser.Rest(); }
/// <summary> /// Parses CREATE SEQUENCE statement. /// </summary> public static void Parse(PgDatabase database, string statement) { var parser = new Parser(statement); parser.Expect("CREATE", "SEQUENCE"); var sequenceName = parser.ParseIdentifier(); var sequence = new PgSequence(ParserUtils.GetObjectName(sequenceName)); var schemaName = ParserUtils.GetSchemaName(sequenceName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new TeamworkParserException($"CannotFindSchema {schemaName} from {statement}"); } schema.Add(sequence); while (!parser.ExpectOptional(";")) { if (parser.ExpectOptional("INCREMENT")) { parser.ExpectOptional("BY"); #pragma warning disable CS0618 // Type or member is obsolete sequence.Increment = parser.ParseStringCompat(); #pragma warning restore CS0618 // Type or member is obsolete } else if (parser.ExpectOptional("MINVALUE")) { #pragma warning disable CS0618 // Type or member is obsolete sequence.MinValue = parser.ParseStringCompat(); #pragma warning restore CS0618 // Type or member is obsolete } else if (parser.ExpectOptional("MAXVALUE")) { #pragma warning disable CS0618 // Type or member is obsolete sequence.MaxValue = parser.ParseStringCompat(); #pragma warning restore CS0618 // Type or member is obsolete } else if (parser.ExpectOptional("START")) { parser.ExpectOptional("WITH"); #pragma warning disable CS0618 // Type or member is obsolete sequence.StartWith = parser.ParseStringCompat(); #pragma warning restore CS0618 // Type or member is obsolete } else if (parser.ExpectOptional("CACHE")) { #pragma warning disable CS0618 // Type or member is obsolete sequence.Cache = parser.ParseStringCompat(); #pragma warning restore CS0618 // Type or member is obsolete } else if (parser.ExpectOptional("CYCLE")) { sequence.Cycle = true; } else if (parser.ExpectOptional("OWNED", "BY")) { if (parser.ExpectOptional("NONE")) { sequence.Owner = null; } else { sequence.Owner = ParserUtils.GetObjectName(parser.ParseIdentifier()); } } else if (parser.ExpectOptional("NO")) { if (parser.ExpectOptional("MINVALUE")) { sequence.MinValue = null; } else if (parser.ExpectOptional("MAXVALUE")) { sequence.MaxValue = null; } else if (parser.ExpectOptional("CYCLE")) { sequence.Cycle = false; } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } else { throw new TeamworkParserException("CannotParseStringUnsupportedCommand"); } } }
/// <summary> /// Parses CREATE AGGREGATE and CREATE OR REPLACE AGGREGATE statement. /// </summary> public static void Parse(PgDatabase database, string statement) { var parser = new Parser(statement); parser.Expect("CREATE"); parser.Expect("AGGREGATE"); var aggregateName = parser.ParseIdentifier(); var schemaName = ParserUtils.GetSchemaName(aggregateName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new Exception(string.Format("CannotFindSchema {0} for {1}", schemaName, statement)); } var aggregate = new PgAggregate() { Name = ParserUtils.GetObjectName(aggregateName), }; schema.Add(aggregate); parser.Expect("("); var arguments = new List <PgAggregate.Argument>(); var first = true; while (!parser.ExpectOptional(")")) { if (!first) { try { parser.Expect(","); } catch (TeamworkParserException ex) { var tmpArgument = arguments.Last(); // last data type was a name Log.Warn(string.Format("Aggregate {0} had a parameter which was not fully a data type (could be because it contained the name). {1} was ignored!", statement, tmpArgument.DataType), ex); arguments.Remove(tmpArgument); } } var dataType = parser.ParseDataType(); var argument = new PgAggregate.Argument() { DataType = dataType, }; arguments.Add(argument); first = false; } foreach (var argument in arguments) { aggregate.Arguments.Add(argument); } aggregate.Body = parser.Rest(); }
/// <summary> /// Parses the given statement and adds the <see cref="PgType"/> to the <see cref="PgDatabase"/>. /// </summary> /// <param name="database">The <see cref="PgDatabase"/> to which the <see cref="PgType"/> is added.</param> /// <param name="statement">The SQL statement of the <see cref="PgType"/>.</param> public static void Parse(PgDatabase database, string statement) { var parser = new Parser(statement); parser.Expect("CREATE"); parser.Expect("TYPE"); var typeName = parser.ParseIdentifier(); parser.Expect("AS"); // check if type is enum if (parser.ExpectOptional("ENUM")) { var enumEntries = new List <string>(); var columnsExist = parser.ExpectOptional("("); if (columnsExist) { while (!parser.ExpectOptional(")")) { #pragma warning disable CS0618 // Type or member is obsolete var entry = parser.ParseStringCompat(); #pragma warning restore CS0618 // Type or member is obsolete enumEntries.Add(ParserUtils.GetObjectName(entry)); parser.ExpectOptional(","); } } var type = new PgType(ParserUtils.GetObjectName(typeName), true) { EnumEntries = enumEntries, }; var schemaName = ParserUtils.GetSchemaName(typeName, database); if (database.SchemaIsIgnored(schemaName)) { return; } PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new Exception(string.Format("Cannot find schema {0}. Statement {1}", schemaName, statement)); } schema.Add(type); } else { var type = new PgType(ParserUtils.GetObjectName(typeName), false); var arguments = new List <PgArgument>(); // type is no enum parser.Expect("("); var attributeType = new StringBuilder(); while (true) { var name = parser.ParseIdentifier(); var datatype = parser.ParseDataType(); arguments.Add(new PgArgument(name, datatype)); parser.SkipWhitespace(); if (parser.ExpectOptional(")")) { break; } else { parser.Expect(","); } } type.AttributeArguments = arguments; parser.Expect(";"); var schemaName = ParserUtils.GetSchemaName(typeName, database); PgSchema schema = database.GetSchema(schemaName); if (schema == null) { throw new Exception(string.Format("Cannot find schema {0}. Statement {1}", schemaName, statement)); } schema.Add(type); } }