@@ -13835,7 +13835,7 @@ Index.ColumnParams IndexColumnWithParams(): {
1383513835 || (Dialect.POSTGRESQL.name().equals(getAsString(Feature.dialect))
1383613836 && getToken(1).kind != K_ASC && getToken(1).kind != K_DESC
1383713837 && getToken(1).kind != K_NULLS && getToken(1).kind != K_COLLATE
13838- && getToken(1).kind != K_WITH) })
13838+ && getToken(1).kind != K_WITH && getToken(1).kind != K_WITHOUT ) })
1383913839 operatorClass=IndexKeyAttributeName()
1384013840 [ LOOKAHEAD(2) operatorClassParameters=PostgreSqlIndexOptions() ]
1384113841 {
@@ -13852,7 +13852,7 @@ Index.ColumnParams IndexColumnWithParams(): {
1385213852 { if (!postgres) { columnParams.add(sortOrder.image); } } ]
1385313853 [ LOOKAHEAD(2) <K_NULLS> (nullOrdering=<K_FIRST> | nullOrdering=<K_LAST>)
1385413854 { if (!postgres) { columnParams.add("NULLS"); columnParams.add(nullOrdering.image); } } ]
13855- ( LOOKAHEAD(2, { !Dialect.POSTGRESQL.name().equals(getAsString(Feature.dialect)) && getToken(1).kind != K_WITH }) parameter=CreateParameter() { columnParams.addAll(parameter); } )*
13855+ ( LOOKAHEAD(2, { !Dialect.POSTGRESQL.name().equals(getAsString(Feature.dialect)) && getToken(1).kind != K_WITH && getToken(1).kind != K_WITHOUT }) parameter=CreateParameter() { columnParams.addAll(parameter); } )*
1385613856 {
1385713857 column = expression != null
1385813858 ? new Index.ColumnParams(expression,
@@ -13913,7 +13913,11 @@ List<Index.Option> PostgreSqlIndexOptions():
1391313913 { return options; }
1391413914}
1391513915
13916- List<Index.ColumnParams> IndexColumnsWithParamsList() : {
13916+ List<Index.ColumnParams> IndexColumnsWithParamsList():
13917+ { List<Index.ColumnParams> columns; }
13918+ { columns=IndexKeyColumns(false) { return columns; } }
13919+
13920+ List<Index.ColumnParams> IndexKeyColumns(boolean temporal) : {
1391713921 List<Index.ColumnParams> colNames = new ArrayList<Index.ColumnParams>();
1391813922 Index.ColumnParams column = null;
1391913923}
@@ -13932,6 +13936,10 @@ List<Index.ColumnParams> IndexColumnsWithParamsList() : {
1393213936 }
1393313937 )*
1393413938
13939+ [ <K_WITHOUT> <K_OVERLAPS> {
13940+ requireDdlSyntax(temporal, "WITHOUT OVERLAPS requires a PRIMARY KEY or UNIQUE constraint");
13941+ column.setWithoutOverlaps(true);
13942+ } ]
1393513943 ")"
1393613944
1393713945 { return colNames; }
@@ -14714,7 +14722,7 @@ Index TableIndexSpec(boolean createContext):
1471414722 typeToken=<K_PRIMARY> keywordToken=<K_KEY>
1471514723 clustering=SqlServerIndexClustering()
1471614724 [ LOOKAHEAD({ clustering == null && getToken(1).kind != OPENING_BRACKET }) indexName=RelObjectName() ]
14717- columns=IndexColumnsWithParamsList( )
14725+ columns=IndexKeyColumns(true )
1471814726 TableIndexOptions(createContext, indexOptions)
1471914727 {
1472014728 index = new NamedConstraint()
@@ -14733,11 +14741,12 @@ Index TableIndexSpec(boolean createContext):
1473314741 [ LOOKAHEAD({ clustering == null && getToken(1).kind != OPENING_BRACKET
1473414742 && getToken(1).kind != K_USING }) indexName=RelObjectName() ]
1473514743 [ using=UsingIndexType() ]
14736- columns=IndexColumnsWithParamsList( )
14744+ columns=IndexKeyColumns(true )
1473714745 TableIndexOptions(createContext, indexOptions)
1473814746 {
14739- // MySQL ALTER preserves both the constraint symbol and the index name.
14740- if (createContext || Dialect.MYSQL.name().equals(getAsString(Feature.dialect))) {
14747+ // PostgreSQL and MySQL ALTER preserve named constraints separately from index names.
14748+ if (createContext || Dialect.MYSQL.name().equals(getAsString(Feature.dialect))
14749+ || Dialect.POSTGRESQL.name().equals(getAsString(Feature.dialect))) {
1474114750 index = new NamedConstraint()
1474214751 .withIndexName(indexName)
1474314752 .withType(typeToken.image
@@ -15898,16 +15907,55 @@ void ReferentialActionSpec(ForeignKeyReference reference):
1589815907 }
1589915908}
1590015909
15910+ /** Shares column/period boundaries on both sides of a foreign key. */
15911+ List<Index.ColumnParams> ForeignKeyColumns(boolean allowParameters):
15912+ {
15913+ List<Index.ColumnParams> columns = new ArrayList<Index.ColumnParams>();
15914+ Index.ColumnParams column;
15915+ }
15916+ {
15917+ "(" column=ForeignKeyColumn(allowParameters) { columns.add(column); }
15918+ ( "," {
15919+ requireDdlSyntax(!column.isPeriod(), "PERIOD must mark the final foreign key column");
15920+ } column=ForeignKeyColumn(allowParameters) { columns.add(column); } )* ")"
15921+ { return columns; }
15922+ }
15923+
15924+ Index.ColumnParams ForeignKeyColumn(boolean allowParameters):
15925+ {
15926+ boolean period = false;
15927+ String name;
15928+ List<String> parameters = null;
15929+ }
15930+ {
15931+ [ LOOKAHEAD({ isKeywordAhead("PERIOD") && getToken(2).kind != K_COMMA
15932+ && getToken(2).kind != CLOSING_BRACKET })
15933+ ContextualKeyword("PERIOD") { period = true; } ]
15934+ name=RelObjectName()
15935+ [ parameters=CreateParameter() {
15936+ requireDdlSyntax(allowParameters && !period, "Expected a foreign key column name");
15937+ } ]
15938+ { return new Index.ColumnParams(name, parameters).withPeriod(period); }
15939+ }
15940+
1590115941ForeignKeyReference ForeignKeyReferenceSpec(boolean columnContext):
1590215942{
1590315943 ForeignKeyReference reference = new ForeignKeyReference();
1590415944 ForeignKeyReference.MatchType matchType;
1590515945 Token matchToken;
1590615946 List<String> refColNames = null;
15947+ List<Index.ColumnParams> referencedColumns;
1590715948 Table fkTable;
1590815949}
1590915950{
15910- <K_REFERENCES> fkTable=Table() [ LOOKAHEAD(2) refColNames=ColumnsNamesList() ]
15951+ <K_REFERENCES> fkTable=Table()
15952+ [ LOOKAHEAD(2) referencedColumns=ForeignKeyColumns(false) {
15953+ refColNames = new ArrayList<String>();
15954+ for (Index.ColumnParams column : referencedColumns) {
15955+ refColNames.add(column.getColumnName());
15956+ }
15957+ reference.setUsingPeriod(referencedColumns.get(referencedColumns.size() - 1).isPeriod());
15958+ } ]
1591115959 {
1591215960 reference.setTable(fkTable);
1591315961 reference.setReferencedColumnNames(refColNames);
@@ -15976,7 +16024,7 @@ ForeignKeyIndex ForeignKeySpec(String constraintName):
1597616024{
1597716025 tk=<K_FOREIGN> tk2=<K_KEY>
1597816026 [ LOOKAHEAD(2) indexName=RelObjectName() { fkIndex.setIndexName(indexName); } ]
15979- colNames = ColumnNamesWithParamsList( )
16027+ colNames = ForeignKeyColumns(true )
1598016028 {
1598116029 if (constraintName != null) { fkIndex.setName(constraintName); }
1598216030 fkIndex.withType(tk.image + " " + tk2.image).withColumns(colNames);
0 commit comments