コード例 #1
0
ファイル: trigger.c プロジェクト: eulerto/pgquarrel
void
dumpAlterTrigger(FILE *output, PQLTrigger *a, PQLTrigger *b)
{
	char	*trgname1 = formatObjectIdentifier(a->trgname);
	char	*trgname2 = formatObjectIdentifier(b->trgname);
	char	*schema2 = formatObjectIdentifier(b->table.schemaname);
	char	*tabname2 = formatObjectIdentifier(b->table.objectname);

	fprintf(output, "\n\n");
	fprintf(output, "ALTER TRIGGER %s ON %s.%s RENAME TO %s;", trgname1, schema2, tabname2, trgname2);

	/* comment */
	if (options.comment)
	{
		if ((a->comment == NULL && b->comment != NULL) ||
				(a->comment != NULL && b->comment != NULL &&
				 strcmp(a->comment, b->comment) != 0))
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON TRIGGER %s ON %s.%s IS '%s';", trgname2, schema2, tabname2, b->comment);
		}
		else if (a->comment != NULL && b->comment == NULL)
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON TRIGGER %s ON %s.%s IS NULL;", trgname2, schema2, tabname2);
		}
	}

	free(trgname1);
	free(trgname2);
	free(schema2);
	free(tabname2);
}
コード例 #2
0
ファイル: sequence.c プロジェクト: fabriziomello/pgquarrel
void
dumpDropSequence(FILE *output, PQLSequence s)
{
	fprintf(output, "\n\n");
	fprintf(output, "DROP SEQUENCE %s.%s;",
			formatObjectIdentifier(s.obj.schemaname),
			formatObjectIdentifier(s.obj.objectname));
}
コード例 #3
0
ファイル: sequence.c プロジェクト: fabriziomello/pgquarrel
PQLSequence *
getSequences(PGconn *c, int *n)
{
	PQLSequence		*s;
	PGresult		*res;
	int				i;

	logNoise("sequence: server version: %d", PQserverVersion(c));

	res = PQexec(c,
				 "SELECT c.oid, n.nspname, c.relname, obj_description(c.oid, 'pg_class') AS description, pg_get_userbyid(c.relowner) AS relowner, relacl FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) WHERE relkind = 'S' AND nspname !~ '^pg_' AND nspname <> 'information_schema' ORDER BY nspname, relname");

	if (PQresultStatus(res) != PGRES_TUPLES_OK)
	{
		logError("query failed: %s", PQresultErrorMessage(res));
		PQclear(res);
		PQfinish(c);
		/* XXX leak another connection? */
		exit(EXIT_FAILURE);
	}

	*n = PQntuples(res);
	if (*n > 0)
		s = (PQLSequence *) malloc(*n * sizeof(PQLSequence));
	else
		s = NULL;

	logDebug("number of sequences in server: %d", *n);

	for (i = 0; i < *n; i++)
	{
		s[i].obj.oid = strtoul(PQgetvalue(res, i, PQfnumber(res, "oid")), NULL, 10);
		s[i].obj.schemaname = strdup(PQgetvalue(res, i, PQfnumber(res, "nspname")));
		s[i].obj.objectname = strdup(PQgetvalue(res, i, PQfnumber(res, "relname")));
		if (PQgetisnull(res, i, PQfnumber(res, "description")))
			s[i].comment = NULL;
		else
			s[i].comment = strdup(PQgetvalue(res, i, PQfnumber(res, "description")));
		if (PQgetisnull(res, i, PQfnumber(res, "description")))
			s[i].comment = NULL;
		else
			s[i].comment = strdup(PQgetvalue(res, i, PQfnumber(res, "description")));

		s[i].owner = strdup(PQgetvalue(res, i, PQfnumber(res, "relowner")));
		if (PQgetisnull(res, i, PQfnumber(res, "relacl")))
			s[i].acl = NULL;
		else
			s[i].acl = strdup(PQgetvalue(res, i, PQfnumber(res, "relacl")));

		logDebug("sequence %s.%s", formatObjectIdentifier(s[i].obj.schemaname),
				 formatObjectIdentifier(s[i].obj.objectname));
	}

	PQclear(res);

	return s;
}
コード例 #4
0
ファイル: rule.c プロジェクト: fabriziomello/pgquarrel
void
dumpDropRule(FILE *output, PQLRule r)
{
	fprintf(output, "\n\n");
	fprintf(output, "DROP RULE %s ON %s.%s;",
			formatObjectIdentifier(r.rulename),
			formatObjectIdentifier(r.table.schemaname),
			formatObjectIdentifier(r.table.objectname));
}
コード例 #5
0
ファイル: collation.c プロジェクト: eulerto/pgquarrel
void
dumpDropCollation(FILE *output, PQLCollation *c)
{
	char	*schema = formatObjectIdentifier(c->obj.schemaname);
	char	*collname = formatObjectIdentifier(c->obj.objectname);

	fprintf(output, "\n\n");
	fprintf(output, "DROP COLLATION %s.%s;",
			schema, collname);

	free(schema);
	free(collname);
}
コード例 #6
0
ファイル: trigger.c プロジェクト: eulerto/pgquarrel
void
dumpDropTrigger(FILE *output, PQLTrigger *t)
{
	char	*trgname = formatObjectIdentifier(t->trgname);
	char	*schema = formatObjectIdentifier(t->table.schemaname);
	char	*tabname = formatObjectIdentifier(t->table.objectname);

	fprintf(output, "\n\n");
	fprintf(output, "DROP TRIGGER %s ON %s.%s;", trgname, schema, tabname);

	free(trgname);
	free(schema);
	free(tabname);
}
コード例 #7
0
ファイル: rule.c プロジェクト: fabriziomello/pgquarrel
PQLRule *
getRules(PGconn *c, int *n)
{
	PQLRule		*r;
	PGresult	*res;
	int			i;

	logNoise("rule: server version: %d", PQserverVersion(c));

	res = PQexec(c,
				"SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition, obj_description(r.oid, 'pg_rewrite') AS description FROM pg_rewrite r INNER JOIN pg_class c ON (c.oid = r.ev_class) INNER JOIN pg_namespace n ON (n.oid = c.relnamespace) WHERE r.rulename <> '_RETURN'::name AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' ORDER BY n.nspname, c.relname, r.rulename");

	if (PQresultStatus(res) != PGRES_TUPLES_OK)
	{
		logError("query failed: %s", PQresultErrorMessage(res));
		PQclear(res);
		PQfinish(c);
		/* XXX leak another connection? */
		exit(EXIT_FAILURE);
	}

	*n = PQntuples(res);
	if (*n > 0)
		r = (PQLRule *) malloc(*n * sizeof(PQLRule));
	else
		r = NULL;

	logDebug("number of rules in server: %d", *n);

	for (i = 0; i < *n; i++)
	{
		r[i].table.schemaname = strdup(PQgetvalue(res, i, PQfnumber(res, "schemaname")));
		r[i].table.objectname = strdup(PQgetvalue(res, i, PQfnumber(res, "tablename")));
		r[i].rulename = strdup(PQgetvalue(res, i, PQfnumber(res, "rulename")));
		r[i].ruledef = strdup(PQgetvalue(res, i, PQfnumber(res, "definition")));
		if (PQgetisnull(res, i, PQfnumber(res, "description")))
			r[i].comment = NULL;
		else
			r[i].comment = strdup(PQgetvalue(res, i, PQfnumber(res, "description")));
		logDebug("rule %s on %s.%s", formatObjectIdentifier(r[i].rulename), formatObjectIdentifier(r[i].table.schemaname), formatObjectIdentifier(r[i].table.objectname));
	}

	PQclear(res);

	return r;
}
コード例 #8
0
ファイル: rule.c プロジェクト: fabriziomello/pgquarrel
void
dumpCreateRule(FILE *output, PQLRule r)
{
	fprintf(output, "\n\n");
	fprintf(output, "%s", r.ruledef);

	/* comment */
	if (options.comment && r.comment != NULL)
	{
		fprintf(output, "\n\n");
		fprintf(output, "COMMENT ON RULE %s ON %s.%s IS '%s';",
				formatObjectIdentifier(r.rulename),
				formatObjectIdentifier(r.table.schemaname),
				formatObjectIdentifier(r.table.objectname),
				r.comment);
	}
}
コード例 #9
0
ファイル: collation.c プロジェクト: eulerto/pgquarrel
void
dumpAlterCollation(FILE *output, PQLCollation *a, PQLCollation *b)
{
	char	*schema2 = formatObjectIdentifier(b->obj.schemaname);
	char	*collname2 = formatObjectIdentifier(b->obj.objectname);

	/* comment */
	if (options.comment)
	{
		if ((a->comment == NULL && b->comment != NULL) ||
				(a->comment != NULL && b->comment != NULL &&
				 strcmp(a->comment, b->comment) != 0))
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON COLLATION %s.%s IS '%s';",
					schema2,
					collname2,
					b->comment);
		}
		else if (a->comment != NULL && b->comment == NULL)
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON COLLATION %s.%s IS NULL;",
					schema2,
					collname2);
		}
	}

	/* owner */
	if (options.owner)
	{
		if (strcmp(a->owner, b->owner) != 0)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER COLLATION %s.%s OWNER TO %s;",
					schema2,
					collname2,
					b->owner);
		}
	}

	free(schema2);
	free(collname2);
}
コード例 #10
0
ファイル: extension.c プロジェクト: eulerto/pgquarrel
void
dumpDropExtension(FILE *output, PQLExtension *e)
{
	char	*extname = formatObjectIdentifier(e->extensionname);

	fprintf(output, "\n\n");
	fprintf(output, "DROP EXTENSION %s;", extname);

	free(extname);
}
コード例 #11
0
ファイル: language.c プロジェクト: eulerto/pgquarrel
void
dumpDropLanguage(FILE *output, PQLLanguage *l)
{
	char	*langname = formatObjectIdentifier(l->languagename);

	fprintf(output, "\n\n");
	fprintf(output, "DROP LANGUAGE %s;", langname);

	free(langname);
}
コード例 #12
0
ファイル: collation.c プロジェクト: eulerto/pgquarrel
void
dumpCreateCollation(FILE *output, PQLCollation *c)
{
	char	*schema = formatObjectIdentifier(c->obj.schemaname);
	char	*collname = formatObjectIdentifier(c->obj.objectname);

	/*
	 * All pg_conversion columns are not null, specifying collate and ctype are
	 * more flexible than locale because locale implies we can't specify
	 * collate or ctype.
	 */
	fprintf(output, "\n\n");
	fprintf(output, "CREATE COLLATION %s.%s (LC_COLLATE = '%s', LC_CTYPE = '%s');",
			schema,
			collname,
			c->collate,
			c->ctype);

	/* comment */
	if (options.comment && c->comment != NULL)
	{
		fprintf(output, "\n\n");
		fprintf(output, "COMMENT ON COLLATION %s.%s IS '%s';",
				schema,
				collname,
				c->comment);
	}

	/* owner */
	if (options.owner)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER COLLATION %s.%s OWNER TO %s;",
				schema,
				collname,
				c->owner);
	}

	free(schema);
	free(collname);
}
コード例 #13
0
ファイル: trigger.c プロジェクト: eulerto/pgquarrel
void
dumpCreateTrigger(FILE *output, PQLTrigger *t)
{
	char	*trgname = formatObjectIdentifier(t->trgname);
	char	*schema = formatObjectIdentifier(t->table.schemaname);
	char	*tabname = formatObjectIdentifier(t->table.objectname);

	fprintf(output, "\n\n");
	fprintf(output, "%s;", t->trgdef);

	/* comment */
	if (options.comment && t->comment != NULL)
	{
		fprintf(output, "\n\n");
		fprintf(output, "COMMENT ON TRIGGER %s ON %s.%s IS '%s';", trgname, schema, tabname, t->comment);
	}

	free(trgname);
	free(schema);
	free(tabname);
}
コード例 #14
0
ファイル: sequence.c プロジェクト: fabriziomello/pgquarrel
void
dumpCreateSequence(FILE *output, PQLSequence s)
{
	fprintf(output, "\n\n");
	fprintf(output, "CREATE SEQUENCE %s.%s",
			formatObjectIdentifier(s.obj.schemaname),
			formatObjectIdentifier(s.obj.objectname));

	/*
	 * dump only if it is not default
	 */
	if (strcmp(s.incvalue, "1") != 0)
		fprintf(output, " INCREMENT BY %s", s.incvalue);

	if ((s.incvalue > 0 && strcmp(s.minvalue, "1") != 0) ||
			(s.incvalue < 0 && strcmp(s.minvalue, MINIMUM_SEQUENCE_VALUE) != 0))
		fprintf(output, " MINVALUE %s", s.minvalue);

	if ((s.incvalue > 0 && strcmp(s.maxvalue, MAXIMUM_SEQUENCE_VALUE) != 0) ||
			(s.incvalue < 0 && strcmp(s.maxvalue, "-1") != 0))
		fprintf(output, " MAXVALUE %s", s.maxvalue);

	if ((s.incvalue > 0 && strcmp(s.startvalue, s.minvalue) != 0) ||
			(s.incvalue < 0 && strcmp(s.startvalue, s.maxvalue) != 0))
		fprintf(output, " START WITH %s", s.startvalue);

	if (strcmp(s.cache, "1") != 0)
		fprintf(output, " CACHE %s", s.cache);

	if (s.cycle)
		fprintf(output, " CYCLE");

	fprintf(output, ";");

	/* comment */
	if (options.comment && s.comment != NULL)
	{
		fprintf(output, "\n\n");
		fprintf(output, "COMMENT ON SEQUENCE %s.%s IS '%s';",
				formatObjectIdentifier(s.obj.schemaname),
				formatObjectIdentifier(s.obj.objectname),
				s.comment);
	}

	/* owner */
	if (options.owner)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER SEQUENCE %s.%s OWNER TO %s;",
				formatObjectIdentifier(s.obj.schemaname),
				formatObjectIdentifier(s.obj.objectname),
				s.owner);
	}

	/* privileges */
	/* XXX second s.obj isn't used. Add an invalid PQLObject? */
	if (options.privileges)
		dumpGrantAndRevoke(output, PGQ_SEQUENCE, s.obj, s.obj, NULL, s.acl, NULL);
}
コード例 #15
0
ファイル: rule.c プロジェクト: fabriziomello/pgquarrel
void
dumpAlterRule(FILE *output, PQLRule a, PQLRule b)
{
	if (strcmp(a.rulename, b.rulename) != 0)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER RULE %s ON %s.%s RENAME TO %s;",
				formatObjectIdentifier(a.rulename),
				formatObjectIdentifier(b.table.schemaname),
				formatObjectIdentifier(b.table.objectname),
				formatObjectIdentifier(b.rulename));
	}

	/* comment */
	if (options.comment)
	{
		if ((a.comment == NULL && b.comment != NULL) ||
				(a.comment != NULL && b.comment != NULL &&
				 strcmp(a.comment, b.comment) != 0))
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON RULE %s ON %s.%s IS '%s';",
					formatObjectIdentifier(b.rulename),
					formatObjectIdentifier(b.table.schemaname),
					formatObjectIdentifier(b.table.objectname),
					b.comment);
		}
		else if (a.comment != NULL && b.comment == NULL)
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON RULE %s ON %s.%s IS NULL;",
					formatObjectIdentifier(b.rulename),
					formatObjectIdentifier(b.table.schemaname),
					formatObjectIdentifier(b.table.objectname));
		}
	}
}
コード例 #16
0
ファイル: extension.c プロジェクト: eulerto/pgquarrel
void
dumpAlterExtension(FILE *output, PQLExtension *a, PQLExtension *b)
{
	char	*extname2 = formatObjectIdentifier(b->extensionname);

	if (strcmp(a->version, b->version) != 0)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER EXTENSION %s UPDATE TO %s;", extname2, b->version);
	}

	if (strcmp(a->schemaname, b->schemaname) != 0)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER EXTENSION %s SET SCHEMA %s;", extname2, b->schemaname);
	}

	/* comment */
	if (options.comment)
	{
		if ((a->comment == NULL && b->comment != NULL) ||
				(a->comment != NULL && b->comment != NULL &&
				 strcmp(a->comment, b->comment) != 0))
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON EXTENSION %s IS '%s';", extname2, b->comment);
		}
		else if (a->comment != NULL && b->comment == NULL)
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON EXTENSION %s IS NULL;", extname2);
		}
	}

	free(extname2);
}
コード例 #17
0
ファイル: extension.c プロジェクト: eulerto/pgquarrel
void
dumpCreateExtension(FILE *output, PQLExtension *e)
{
	char	*extname = formatObjectIdentifier(e->extensionname);

	fprintf(output, "\n\n");
	fprintf(output, "CREATE EXTENSION %s", extname);

	if (e->relocatable)
		fprintf(output, " WITH SCHEMA %s", e->schemaname);

	fprintf(output, " VERSION '%s'", e->version);

	fprintf(output, ";");

	/* comment */
	if (options.comment && e->comment != NULL)
	{
		fprintf(output, "\n\n");
		fprintf(output, "COMMENT ON EXTENSION %s IS '%s';", extname, e->comment);
	}

	free(extname);
}
コード例 #18
0
ファイル: language.c プロジェクト: eulerto/pgquarrel
void
dumpAlterLanguage(FILE *output, PQLLanguage *a, PQLLanguage *b)
{
	char	*langname1 = formatObjectIdentifier(a->languagename);
	char	*langname2 = formatObjectIdentifier(b->languagename);

	if (strcmp(a->languagename, b->languagename) != 0)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER LANGUAGE %s RENAME TO %s;", langname1, langname2);
	}

	/* comment */
	if (options.comment)
	{
		if ((a->comment == NULL && b->comment != NULL) ||
				(a->comment != NULL && b->comment != NULL &&
				 strcmp(a->comment, b->comment) != 0))
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON LANGUAGE %s IS '%s';", langname2, b->comment);
		}
		else if (a->comment != NULL && b->comment == NULL)
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON LANGUAGE %s IS NULL;", langname2);
		}
	}

	/* security labels */
	if (options.securitylabels)
	{
		if (a->seclabels == NULL && b->seclabels != NULL)
		{
			int	i;

			for (i = 0; i < b->nseclabels; i++)
			{
				fprintf(output, "\n\n");
				fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS '%s';",
						b->seclabels[i].provider,
						langname2,
						b->seclabels[i].label);
			}
		}
		else if (a->seclabels != NULL && b->seclabels == NULL)
		{
			int	i;

			for (i = 0; i < a->nseclabels; i++)
			{
				fprintf(output, "\n\n");
				fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS NULL;",
						a->seclabels[i].provider,
						langname1);
			}
		}
		else if (a->seclabels != NULL && b->seclabels != NULL)
		{
			int	i, j;

			i = j = 0;
			while (i < a->nseclabels || j < b->nseclabels)
			{
				if (i == a->nseclabels)
				{
					fprintf(output, "\n\n");
					fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS '%s';",
							b->seclabels[j].provider,
							langname2,
							b->seclabels[j].label);
					j++;
				}
				else if (j == b->nseclabels)
				{
					fprintf(output, "\n\n");
					fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS NULL;",
							a->seclabels[i].provider,
							langname1);
					i++;
				}
				else if (strcmp(a->seclabels[i].provider, b->seclabels[j].provider) == 0)
				{
					if (strcmp(a->seclabels[i].label, b->seclabels[j].label) != 0)
					{
						fprintf(output, "\n\n");
						fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS '%s';",
								b->seclabels[j].provider,
								langname2,
								b->seclabels[j].label);
					}
					i++;
					j++;
				}
				else if (strcmp(a->seclabels[i].provider, b->seclabels[j].provider) < 0)
				{
					fprintf(output, "\n\n");
					fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS NULL;",
							a->seclabels[i].provider,
							langname1);
					i++;
				}
				else if (strcmp(a->seclabels[i].provider, b->seclabels[j].provider) > 0)
				{
					fprintf(output, "\n\n");
					fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS '%s';",
							b->seclabels[j].provider,
							langname2,
							b->seclabels[j].label);
					j++;
				}
			}
		}
	}

	/* owner */
	if (options.owner)
	{
		if (strcmp(a->owner, b->owner) != 0)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER LANGUAGE %s OWNER TO %s;",
					langname2,
					b->owner);
		}
	}

	/* privileges */
	if (options.privileges)
	{
		PQLObject tmpa, tmpb;

		tmpa.schemaname = NULL;
		tmpa.objectname = a->languagename;
		tmpb.schemaname = NULL;
		tmpb.objectname = b->languagename;

		if (a->acl != NULL || b->acl != NULL)
			dumpGrantAndRevoke(output, PGQ_LANGUAGE, &tmpa, &tmpb, a->acl, b->acl, NULL, NULL);
	}

	free(langname1);
	free(langname2);
}
コード例 #19
0
ファイル: language.c プロジェクト: eulerto/pgquarrel
void
dumpCreateLanguage(FILE *output, PQLLanguage *l)
{
	char	*langname = formatObjectIdentifier(l->languagename);

	fprintf(output, "\n\n");
	fprintf(output, "CREATE LANGUAGE %s", langname);

	if (!l->pltemplate)
	{
		if (l->trusted)
			fprintf(output, " TRUSTED");

		fprintf(output, " HANDLER %s", l->callhandler);
		fprintf(output, " INLINE %s", l->inlinehandler);
		fprintf(output, " VALIDATOR %s", l->validator);
	}

	fprintf(output, ";");

	/* comment */
	if (options.comment && l->comment != NULL)
	{
		fprintf(output, "\n\n");
		fprintf(output, "COMMENT ON LANGUAGE %s IS '%s';", langname, l->comment);
	}

	/* security labels */
	if (options.securitylabels && l->nseclabels > 0)
	{
		int	i;

		for (i = 0; i < l->nseclabels; i++)
		{
			fprintf(output, "\n\n");
			fprintf(output, "SECURITY LABEL FOR %s ON LANGUAGE %s IS '%s';",
					l->seclabels[i].provider,
					langname,
					l->seclabels[i].label);
		}
	}

	/* owner */
	if (options.owner)
	{
		fprintf(output, "\n\n");
		fprintf(output, "ALTER LANGUAGE %s OWNER TO %s;",
				langname,
				l->owner);
	}

	/* privileges */
	/* XXX second s.obj isn't used. Add an invalid PQLObject? */
	if (options.privileges)
	{
		PQLObject tmp;

		tmp.schemaname = NULL;
		tmp.objectname = l->languagename;

		dumpGrantAndRevoke(output, PGQ_LANGUAGE, &tmp, &tmp, NULL, l->acl, NULL, NULL);
	}

	free(langname);
}
コード例 #20
0
ファイル: sequence.c プロジェクト: fabriziomello/pgquarrel
void
dumpAlterSequence(FILE *output, PQLSequence a, PQLSequence b)
{
	bool	printalter = true;

	if (strcmp(a.incvalue, b.incvalue) != 0)
	{
		if (printalter)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
		printalter = false;

		fprintf(output, " INCREMENT BY %s", b.incvalue);
	}

	if (strcmp(a.minvalue, b.minvalue) != 0)
	{
		if (printalter)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
		printalter = false;

		fprintf(output, " MINVALUE %s", b.minvalue);
	}

	if (strcmp(a.maxvalue, b.maxvalue) != 0)
	{
		if (printalter)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
		printalter = false;

		fprintf(output, " MAXVALUE %s", b.maxvalue);
	}

	if (strcmp(a.startvalue, b.startvalue) != 0)
	{
		if (printalter)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
		printalter = false;

		fprintf(output, " START WITH %s RESTART WITH %s", b.startvalue, b.startvalue);
	}

	if (strcmp(a.cache, b.cache) != 0)
	{
		if (printalter)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
		printalter = false;

		fprintf(output, " CACHE %s", b.cache);
	}

	if (a.cycle != b.cycle)
	{
		if (printalter)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
		printalter = false;

		if (b.cycle)
			fprintf(output, " CYCLE");
		else
			fprintf(output, " NO CYCLE");
	}

	if (!printalter)
		fprintf(output, ";");

	/* comment */
	if (options.comment)
	{
		if ((a.comment == NULL && b.comment != NULL) ||
				(a.comment != NULL && b.comment != NULL &&
				 strcmp(a.comment, b.comment) != 0))
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON SEQUENCE %s.%s IS '%s';",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname),
					b.comment);
		}
		else if (a.comment != NULL && b.comment == NULL)
		{
			fprintf(output, "\n\n");
			fprintf(output, "COMMENT ON SEQUENCE %s.%s IS NULL;",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname));
		}
	}

	/* owner */
	if (options.owner)
	{
		if (strcmp(a.owner, b.owner) != 0)
		{
			fprintf(output, "\n\n");
			fprintf(output, "ALTER SEQUENCE %s.%s OWNER TO %s;",
					formatObjectIdentifier(b.obj.schemaname),
					formatObjectIdentifier(b.obj.objectname),
					b.owner);
		}
	}

	/* privileges */
	if (options.privileges)
	{
		if (a.acl != NULL || b.acl != NULL)
			dumpGrantAndRevoke(output, PGQ_SEQUENCE, a.obj, b.obj, a.acl, b.acl, NULL);
	}
}