From 4789ba16724d266cfe5b7a723ac3f75e69dbbce4 Mon Sep 17 00:00:00 2001 From: asfernandes Date: Wed, 4 Sep 2013 15:54:19 +0000 Subject: [PATCH] Improvement CORE-4199 - Add optional START WITH clause to identity columns. --- .../README.identity_columns.txt | 2 +- src/dsql/DdlNodes.epp | 14 ++++++-------- src/dsql/DdlNodes.h | 4 +++- src/dsql/parse.y | 19 ++++++++++++++++--- src/isql/extract.epp | 13 +++++++++---- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/doc/sql.extensions/README.identity_columns.txt b/doc/sql.extensions/README.identity_columns.txt index d410c62c60..352ccd4434 100644 --- a/doc/sql.extensions/README.identity_columns.txt +++ b/doc/sql.extensions/README.identity_columns.txt @@ -11,7 +11,7 @@ Description: Syntax: ::= - GENERATED BY DEFAULT AS IDENTITY + GENERATED BY DEFAULT AS IDENTITY [ (START WITH ) ] Syntax rules: - The type of an identity column must be an exact number type with zero scale. That includes: diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 21cc629271..ecb6e2d435 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -4890,13 +4890,7 @@ void CreateAlterSequenceNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_SEQUENCE, name); const SINT64 val = value.specified ? value.value : 0; - - const SSHORT id = store(tdbb, transaction, name, fb_sysflag_user, val); - fb_assert(id > 0); - - // the store() call above has caused the DFW item to be posted, - // so we just adjust the cached generator value - transaction->getGenIdCache()->put(id, val); + store(tdbb, transaction, name, fb_sysflag_user, val); executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_SEQUENCE, name); } @@ -5012,6 +5006,10 @@ SSHORT CreateAlterSequenceNode::store(thread_db* tdbb, jrd_tra* transaction, con storePrivileges(tdbb, transaction, name, obj_generator, USAGE_PRIVILEGES); + // The STORE above has caused the DFW item to be posted, so we just adjust the cached + // generator value. + transaction->getGenIdCache()->put(storedId, val); + return storedId; } @@ -5546,7 +5544,7 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch DYN_UTIL_generate_generator_name(tdbb, fieldDefinition.identitySequence); CreateAlterSequenceNode::store(tdbb, transaction, fieldDefinition.identitySequence, - fb_sysflag_identity_generator, 0); + fb_sysflag_identity_generator, clause->identityStart); } BlrDebugWriter::BlrData defaultValue; diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index 674474720b..f57b09e96d 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -1168,7 +1168,8 @@ public: constraints(p), collate(p), computed(NULL), - identity(false) + identity(false), + identityStart(0) { } @@ -1178,6 +1179,7 @@ public: Firebird::MetaName collate; NestConst computed; bool identity; + SINT64 identityStart; }; struct AlterColNameClause : public Clause diff --git a/src/dsql/parse.y b/src/dsql/parse.y index 45fa67e36e..69eeb490ae 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -1466,8 +1466,13 @@ generator_clause %type start_with_opt start_with_opt - : /* nothing */ { $$ = Nullable::empty(); } - | START WITH sequence_value { $$ = Nullable::val($3); } + : /* nothing */ { $$ = Nullable::empty(); } + | start_with { $$ = Nullable::val($1); } + ; + +%type start_with +start_with + : START WITH sequence_value { $$ = $3; } ; %type replace_sequence_clause @@ -1805,6 +1810,7 @@ column_def($relationNode) clause->field = $2; clause->field->fld_name = *$1; clause->identity = true; + clause->identityStart = $3; $relationNode->clauses.add(clause); } column_constraint_clause(NOTRIAL($4)) collate_clause @@ -1832,8 +1838,15 @@ column_def($relationNode) } ; +%type identity_clause identity_clause - : GENERATED BY DEFAULT AS IDENTITY + : GENERATED BY DEFAULT AS IDENTITY identity_clause_options { $$ = $6; } + ; + +%type identity_clause_options +identity_clause_options + : /* nothing */ { $$ = 0; } + | '(' start_with ')' { $$ = $2; } ; // value does allow parens around it, but there is a problem getting the source text. diff --git a/src/isql/extract.epp b/src/isql/extract.epp index db4a7f4427..aea97709ae 100644 --- a/src/isql/extract.epp +++ b/src/isql/extract.epp @@ -510,12 +510,17 @@ int EXTRACT_list_table(const SCHAR* relation_name, if (ENCODE_ODS(isqlGlob.major_ods, isqlGlob.minor_ods) >= ODS_12_0) { - FOR RFR2 IN RDB$RELATION_FIELDS - WITH RFR2.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME AND + FOR RFR2 IN RDB$RELATION_FIELDS CROSS + GEN IN RDB$GENERATORS + WITH GEN.RDB$GENERATOR_NAME = RFR2.RDB$GENERATOR_NAME AND + RFR2.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME AND RFR2.RDB$FIELD_NAME = RFR.RDB$FIELD_NAME + { - if (!RFR2.RDB$GENERATOR_NAME.NULL) - isqlGlob.printf(" GENERATED BY DEFAULT AS IDENTITY"); + isqlGlob.printf(" GENERATED BY DEFAULT AS IDENTITY"); + + if (!GEN.RDB$INITIAL_VALUE.NULL && GEN.RDB$INITIAL_VALUE != 0) + isqlGlob.printf(" (START WITH %" SQUADFORMAT ")", GEN.RDB$INITIAL_VALUE); } END_FOR ON_ERROR