diff --git a/doc/sql.extensions/README.identity_columns.txt b/doc/sql.extensions/README.identity_columns.txt index 5e97b5d405..5c5970ef8c 100644 --- a/doc/sql.extensions/README.identity_columns.txt +++ b/doc/sql.extensions/README.identity_columns.txt @@ -18,10 +18,13 @@ Syntax: INCREMENT [ BY ] ::= - RESTART [ WITH ] | - SET INCREMENT [ BY ] | + ... | DROP IDENTITY + ::= + RESTART [ WITH ] | + SET INCREMENT [ BY ] + Syntax rules: - The type of an identity column must be an exact number type with zero scale. That includes: smallint, integer, bigint, numeric(x, 0) and decimal(x, 0). diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 83740b621b..a701117574 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -6214,7 +6214,7 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch ObjectsArray constraints; bool notNullFlag = false; - if (clause->identity) + if (clause->identityOptions) notNullFlag = true; // identity columns are implicitly not null for (ObjectsArray::iterator ptr = clause->constraints.begin(); @@ -6277,9 +6277,9 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch if (clause->collate.hasData()) DDL_resolve_intl_type(dsqlScratch, field, clause->collate); - if (clause->identity) + if (clause->identityOptions) { - if (clause->identity->increment.orElse(1) == 0) + if (clause->identityOptions->increment.orElse(1) == 0) { status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_inc_ident) << Arg::Str(field->fld_name) << @@ -6299,8 +6299,8 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch CreateAlterSequenceNode::store(tdbb, transaction, fieldDefinition.identitySequence, fb_sysflag_identity_generator, - clause->identity->start.orElse(0), - clause->identity->increment.orElse(1)); + clause->identityOptions->startValue.orElse(0), + clause->identityOptions->increment.orElse(1)); } BlrDebugWriter::BlrData defaultValue; @@ -7862,7 +7862,7 @@ void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlSc RFR.RDB$IDENTITY_TYPE.NULL = TRUE; END_MODIFY } - else if (clause->identityRestart || clause->identityIncrement.specified) + else if (clause->identityOptions) { bool found = false; AutoRequest request2; @@ -7874,27 +7874,26 @@ void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlSc const SLONG id = GEN.RDB$GENERATOR_ID; const MetaName genName(RFR.RDB$GENERATOR_NAME); - if (clause->identityRestart) + if (clause->identityOptions->restart) { - const SINT64 val = clause->identityRestartValue.specified ? - clause->identityRestartValue.value : - (!GEN.RDB$INITIAL_VALUE.NULL ? GEN.RDB$INITIAL_VALUE : 0); + const SINT64 val = clause->identityOptions->startValue + .orElse(!GEN.RDB$INITIAL_VALUE.NULL ? GEN.RDB$INITIAL_VALUE : 0); transaction->getGenIdCache()->put(id, val); } - else if (clause->identityIncrement.specified) + + if (clause->identityOptions->increment.specified) { - if (clause->identityIncrement.value == 0) + if (clause->identityOptions->increment.value == 0) { status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_inc_ident) << Arg::Str(field->fld_name) << Arg::Str(name)); } - MET_update_generator_increment(tdbb, id, clause->identityIncrement.value); + MET_update_generator_increment(tdbb, id, + clause->identityOptions->increment.value); } - else - fb_assert(false); dsc desc; desc.makeText((USHORT) genName.length(), ttype_metadata, diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index 2604a6765f..a46b7b6db7 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -1307,11 +1307,13 @@ public: struct IdentityOptions { IdentityOptions(MemoryPool&) + : restart(false) { } - Nullable start; + Nullable startValue; Nullable increment; + bool restart; // used in ALTER }; struct AddColumnClause : public Clause @@ -1323,7 +1325,7 @@ public: constraints(p), collate(p), computed(NULL), - identity(NULL), + identityOptions(NULL), notNullSpecified(false) { } @@ -1333,7 +1335,7 @@ public: Firebird::ObjectsArray constraints; Firebird::MetaName collate; NestConst computed; - NestConst identity; + NestConst identityOptions; bool notNullSpecified; }; @@ -1384,7 +1386,7 @@ public: defaultValue(NULL), dropDefault(false), dropIdentity(false), - identityRestart(false), + identityOptions(NULL), computed(NULL) { } @@ -1393,9 +1395,7 @@ public: NestConst defaultValue; bool dropDefault; bool dropIdentity; - bool identityRestart; - Nullable identityRestartValue; - Nullable identityIncrement; + NestConst identityOptions; NestConst computed; }; diff --git a/src/dsql/parse-conflicts.txt b/src/dsql/parse-conflicts.txt index b0587cd258..20cc527f2d 100644 --- a/src/dsql/parse-conflicts.txt +++ b/src/dsql/parse-conflicts.txt @@ -1 +1 @@ -44 shift/reduce conflicts, 17 reduce/reduce conflicts. +45 shift/reduce conflicts, 17 reduce/reduce conflicts. diff --git a/src/dsql/parse.y b/src/dsql/parse.y index cc97817454..491d0a9805 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -2149,7 +2149,7 @@ column_def($relationNode) newNode(); clause->field = $2; clause->field->fld_name = *$1; - clause->identity = $3; + clause->identityOptions = $3; $relationNode->clauses.add(clause); } column_constraint_clause(NOTRIAL($4)) collate_clause @@ -2200,7 +2200,7 @@ identity_clause_options($identityOptions) %type identity_clause_option() identity_clause_option($identityOptions) : START WITH sequence_value - { setClause($identityOptions->start, "START WITH", $3); } + { setClause($identityOptions->startValue, "START WITH", $3); } | INCREMENT by_noise signed_long_integer { setClause($identityOptions->increment, "INCREMENT BY", $3); } ; @@ -3927,23 +3927,16 @@ alter_op($relationNode) clause->dropDefault = true; $relationNode->clauses.add(clause); } - | col_opt symbol_column_name RESTART with_opt - { - RelationNode::AlterColTypeClause* clause = newNode(); - clause->field = newNode(); - clause->field->fld_name = *$2; - clause->identityRestart = true; - clause->identityRestartValue = $4; - $relationNode->clauses.add(clause); - } - | col_opt symbol_column_name SET INCREMENT by_noise signed_long_integer - { - RelationNode::AlterColTypeClause* clause = newNode(); - clause->field = newNode(); - clause->field->fld_name = *$2; - clause->identityIncrement = $6; - $relationNode->clauses.add(clause); - } + | col_opt symbol_column_name + { $$ = newNode(); } + alter_identity_clause_options($3) + { + RelationNode::AlterColTypeClause* clause = newNode(); + clause->field = newNode(); + clause->field->fld_name = *$2; + clause->identityOptions = $3; + $relationNode->clauses.add(clause); + } | col_opt symbol_column_name DROP IDENTITY { RelationNode::AlterColTypeClause* clause = newNode(); @@ -4082,6 +4075,23 @@ alter_data_type_or_domain } ; +%type alter_identity_clause_options() +alter_identity_clause_options($identityOptions) + : alter_identity_clause_options alter_identity_clause_option($identityOptions) + | alter_identity_clause_option($identityOptions) + ; + +%type alter_identity_clause_option() +alter_identity_clause_option($identityOptions) + : RESTART with_opt + { + setClause($identityOptions->restart, "RESTART"); + $identityOptions->startValue = $2; + } + | SET INCREMENT by_noise signed_long_integer + { setClause($identityOptions->increment, "SET INCREMENT BY", $4); } + ; + %type drop_behaviour drop_behaviour : { $$ = false; }