Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public void setParameters(List<Sequence.Parameter> parameters) {
this.parameters = parameters == null ? null : new ArrayList<>(parameters);
}

/** Returns the restart value, or null for a bare RESTART using the sequence start value. */
public Long getRestartWith() {
return restartWith;
}
Expand All @@ -69,6 +70,11 @@ public void setRestartWith(Long restartWith) {
this.restartWith = restartWith;
}

public IdentityAlteration withRestartWith(Long restartWith) {
setRestartWith(restartWith);
return this;
}

public boolean isIfExists() {
return ifExists;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -16306,7 +16306,7 @@ IdentityAlteration ColumnIdentityAlteration():
}
)
|
<K_RESTART> [ LOOKAHEAD(2) <K_WITH> restart=SequenceParameterValue() ] {
<K_RESTART> [ LOOKAHEAD(1) [ <K_WITH> ] restart=SequenceParameterValue() ] {
alteration = new IdentityAlteration(IdentityAlteration.Kind.RESTART);
alteration.setRestartWith(restart);
}
Expand Down
7 changes: 7 additions & 0 deletions src/site/sphinx/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ Table constraints expose ``Index.getNullsDistinct()``, ``getIncludeColumns()``,

Identity alterations are available as ``ColumnDataType.getIdentityAlterations()``. Sequence ownership is shared by ``CreateSequence`` and ``AlterSequence`` through ``Sequence.getOwnership()``: ``null`` means omitted, ``isNone()`` means explicit ``OWNED BY NONE``, and ``getColumn()`` identifies an owner. ``TablesNamesFinder`` includes ``LIKE`` sources and sequence owners without treating sequence or type names as tables. See `ALTER TABLE <https://www.postgresql.org/docs/18/sql-altertable.html>`_ and `ALTER SEQUENCE <https://www.postgresql.org/docs/18/sql-altersequence.html>`_.

For identity columns, ``RESTART 20`` and ``RESTART WITH 20`` produce the same
``IdentityAlteration`` with kind ``RESTART`` and ``getRestartWith() == 20L``.
The renderer consistently uses ``RESTART WITH 20``. A null restart value means
bare ``RESTART``, which uses the sequence's configured start value. Call
``setRestartWith`` to edit a parsed action or construct one with
``new IdentityAlteration(Kind.RESTART).withRestartWith(20L)``.


Structured column attributes
============================
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2026 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.statement.alter;

import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.AbstractJSqlParser.Dialect;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.util.deparser.StatementDeParser;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class IdentityRestartValueTest {
@ParameterizedTest
@ValueSource(strings = {"20", "WITH 20", "+20", "-20", "WITH -20", "9223372036854775807"})
void representsOptionalWithUsingTheSameValue(String value) throws JSQLParserException {
for (Dialect dialect : new Dialect[] {null, Dialect.POSTGRESQL}) {
Alter alter = parse("ALTER TABLE t ALTER COLUMN id RESTART " + value, dialect);
IdentityAlteration restart = identity(alter).get(0);
assertEquals(IdentityAlteration.Kind.RESTART, restart.getKind());
assertEquals(Long.valueOf(value.replace("WITH ", "")), restart.getRestartWith());
roundTrip(alter, dialect);
}
}

@Test
void editsAndConstructsRestartAndPreservesBareRestart() throws JSQLParserException {
Alter alter = parse("ALTER TABLE t ALTER COLUMN id RESTART", Dialect.POSTGRESQL);
assertNull(identity(alter).get(0).getRestartWith());
identity(alter).get(0).setRestartWith(20L);
assertEquals("ALTER TABLE t ALTER COLUMN id RESTART WITH 20", alter.toString());
roundTrip(alter, Dialect.POSTGRESQL);
alter.getAlterExpressions().get(0).getColDataTypeList().get(0).setIdentityAlterations(
List.of(new IdentityAlteration(IdentityAlteration.Kind.RESTART)
.withRestartWith(40L)));
assertEquals("ALTER TABLE t ALTER COLUMN id RESTART WITH 40", alter.toString());
roundTrip(alter, Dialect.POSTGRESQL);
identity(alter).get(0).setRestartWith(null);
assertEquals("ALTER TABLE t ALTER COLUMN id RESTART", alter.toString());
}

@Test
void respectsIdentityAndAlterActionBoundaries() throws JSQLParserException {
Alter alter = parse(
"ALTER TABLE t ALTER COLUMN id SET CACHE 10 RESTART 20 SET NO CYCLE, ADD COLUMN extra INT",
Dialect.POSTGRESQL);
assertEquals(3, identity(alter).size());
assertEquals(2, alter.getAlterExpressions().size());
roundTrip(alter, Dialect.POSTGRESQL);
roundTrip(parse("ALTER TABLE t ALTER COLUMN id RESTART SET CACHE 10", Dialect.POSTGRESQL),
Dialect.POSTGRESQL);
assertThrows(JSQLParserException.class,
() -> parse("ALTER TABLE t ALTER COLUMN id RESTART WITH", Dialect.POSTGRESQL));
}

private static List<IdentityAlteration> identity(Alter alter) {
return alter.getAlterExpressions().get(0).getColDataTypeList().get(0)
.getIdentityAlterations();
}

private static Alter parse(String sql, Dialect dialect) throws JSQLParserException {
return (Alter) CCJSqlParserUtil.parse(sql, p -> {
if (dialect != null) {
p.withDialect(dialect);
}
});
}

private static void roundTrip(Alter alter, Dialect dialect) throws JSQLParserException {
StringBuilder sql = new StringBuilder();
alter.accept(new StatementDeParser(sql), null);
assertEquals(alter.toString(), sql.toString());
assertEquals(sql.toString(), parse(sql.toString(), dialect).toString());
}
}
Loading