#coding:utf-8 """ ID: issue-5733 ISSUE: 5733 TITLE: Support GENERATED ALWAYS identity columns and OVERRIDE clause DESCRIPTION: JIRA: CORE-5463 FBTEST: bugs.core_5463 NOTES: [18.07.2023] pzotov Adjusted STDERR text after changes related to fixed gh-7638 ("OVERRIDING USER VALUE should be allowed for GENERATED ALWAYS AS IDENTITY."), see: https://github.com/FirebirdSQL/firebird/commit/844631b0ee473fd94dab61558f146a8268c0967b https://github.com/FirebirdSQL/firebird/commit/43c5426b48b2647c795143fcaa4a8e20c57fc9c8 Old text: "OVERRIDING SYSTEM VALUE should be used to override the value of an identity column defined as 'GENERATED ALWAYS' in table/view ..." New text (after #7638 was fixed): "OVERRIDING clause should be used when an identity column defined as 'GENERATED ALWAYS' is present in the INSERT's field list for table table/view ..." """ import pytest from firebird.qa import * db = db_factory() test_script = """ set list on; recreate table test_always( id_always int generated ALWAYS as identity (start with 11 increment 22) unique ); recreate table test_default( id_default int generated BY DEFAULT as identity (start with -11 increment -22) unique ); insert into test_default default values returning id_default; -- expected: -33 insert into test_always default values returning id_always; -- expected: 33 -- Comments taken from doc\\sql.extensions\\README.identity_columns.txt -- ================================================================== -- ........................................ -- Identity columns are implicitly NOT NULL -- ........................................ -- Statement failed, SQLSTATE = 42000 -- ::: NB ::: Error text was changed for following statement. -- 1. For FB 5.x - since 28-JUN-2023 (old text was up to build 5.0.0.1088, new appeared since 5.0.0.1093) -- 2. For FB 4.x - since 08-JUL-2023 (old text was up to build 4.0.3.2958, new appeared since 4.0.3.2963) -- OLD TEXT: OVERRIDING SYSTEM VALUE should be used to override the value of an identity column defined as 'GENERATED ALWAYS' in table/view TEST_ALWAYS -- NEW TEXT: OVERRIDING clause should be used when an identity column defined as 'GENERATED ALWAYS' is present in the INSERT's field list for table table/view TEST_ALWAYS insert into test_always(id_always) values(null); -- Statement failed, SQLSTATE = 23000 -- validation error for column "TEST"."id_default", value "*** null ***" insert into test_default(id_default) values(null); -- ........................................................................ -- BY DEFAULT identity columns can be overriden in INSERT statements -- just specifying the value in the values list -- ........................................................................ insert into test_default(id_default) values(-7654321) returning id_default; -- insert into test_default default values returning id_default; ==> -99 ! -- ........................................................................ -- However, for ALWAYS identity columns that is not allowed. -- To use the value passed in the INSERT statement for an ALWAYS column, you should pass -- OVERRIDING SYSTEM VALUE: -- ........................................................................ -- 1) check that OVERRIDING SYSTEM VALUE clause does not affect on NOT_NULL constraint: -- Statement failed, SQLSTATE = 23000 -- validation error for column "test_always"."ID_ALWAYS", value "*** null ***" insert into test_always(id_always) overriding system value values (null) returning id_always; -- 2) check ability to override system value by providing our own: insert into test_always(id_always) overriding system value values (7654321) returning id_always; -- ......................................................................... -- OVERRIDING also supports a subclause to be used with BY DEFAULT columns, -- to ignore the value passed in INSERT and use the defined sequence: -- ......................................................................... -- 1) check that attempt to pass NULL into VALUES list has no effect: insert into test_default(id_default) overriding user value values(null) returning id_default; -- expected: -99 -- 2) check ability to pass allowed value but it also must be overriden by default one: insert into test_default(id_default) overriding user value values(-7654322) returning id_default; -- expected: -121 """ act = isql_act('db', test_script) expected_stdout = """ ID_DEFAULT -11 ID_ALWAYS 11 ID_DEFAULT -7654321 ID_ALWAYS 7654321 ID_DEFAULT -33 ID_DEFAULT -55 """ expected_stderr = """ Statement failed, SQLSTATE = 42000 OVERRIDING clause should be used when an identity column defined as 'GENERATED ALWAYS' is present in the INSERT's field list for table table/view TEST_ALWAYS Statement failed, SQLSTATE = 23000 validation error for column "TEST_DEFAULT"."ID_DEFAULT", value "*** null ***" Statement failed, SQLSTATE = 23000 validation error for column "TEST_ALWAYS"."ID_ALWAYS", value "*** null ***" """ @pytest.mark.version('>=4.0') def test_1(act: Action): act.expected_stdout = expected_stdout act.expected_stderr = expected_stderr act.execute() assert (act.clean_stderr == act.clean_expected_stderr and act.clean_stdout == act.clean_expected_stdout)