@@ -639,17 +639,11 @@ public function testInformationSchemaTablesAutoIncrement(): void {
639639 $ result = $ this ->assertQuery ( "SELECT * FROM information_schema.tables WHERE table_name = 't' " );
640640 $ this ->assertSame ( '1 ' , $ result [0 ]->AUTO_INCREMENT );
641641
642- // After inserts, the stored value advances, and a backtick-quoted
643- // projection returns the same result as SELECT *.
642+ // After inserts, the sequence advances.
644643 $ this ->assertQuery ( "INSERT INTO t (name) VALUES ('a'), ('b'), ('c') " );
645644 $ result = $ this ->assertQuery ( "SELECT * FROM information_schema.tables WHERE table_name = 't' " );
646645 $ this ->assertSame ( '4 ' , $ result [0 ]->AUTO_INCREMENT );
647646
648- $ result = $ this ->assertQuery (
649- "SELECT table_name, `auto_increment` FROM information_schema.tables WHERE table_name = 't' "
650- );
651- $ this ->assertSame ( '4 ' , $ result [0 ]->AUTO_INCREMENT );
652-
653647 // DELETE preserves the counter.
654648 $ this ->assertQuery ( 'DELETE FROM t ' );
655649 $ result = $ this ->assertQuery ( "SELECT * FROM information_schema.tables WHERE table_name = 't' " );
@@ -661,41 +655,60 @@ public function testInformationSchemaTablesAutoIncrement(): void {
661655 $ this ->assertSame ( '1 ' , $ result [0 ]->AUTO_INCREMENT );
662656 }
663657
664- public function testShowTableStatusAutoIncrement () {
658+ public function testInformationSchemaTablesFilterByAutoIncrement (): void {
659+ $ this ->assertQuery ( 'CREATE TABLE low (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
660+ $ this ->assertQuery ( 'CREATE TABLE high (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
661+ $ this ->assertQuery ( 'CREATE TABLE plain (id INT, name TEXT) ' );
662+ $ this ->assertQuery ( "INSERT INTO low (name) VALUES ('a') " );
663+ $ this ->assertQuery ( "INSERT INTO high (name) VALUES ('a'), ('b'), ('c'), ('d'), ('e') " );
664+
665+ $ result = $ this ->assertQuery (
666+ 'SELECT TABLE_NAME FROM information_schema.tables WHERE `AUTO_INCREMENT` > 3 '
667+ );
668+ $ this ->assertCount ( 1 , $ result );
669+ $ this ->assertSame ( 'high ' , $ result [0 ]->TABLE_NAME );
670+
671+ $ result = $ this ->assertQuery (
672+ 'SELECT TABLE_NAME FROM information_schema.tables WHERE `AUTO_INCREMENT` IS NULL '
673+ );
674+ $ this ->assertCount ( 1 , $ result );
675+ $ this ->assertSame ( 'plain ' , $ result [0 ]->TABLE_NAME );
676+ }
677+
678+ public function testShowTableStatusAutoIncrement (): void {
665679 // A non-AUTO_INCREMENT table reports NULL.
666680 $ this ->assertQuery ( 'CREATE TABLE plain (id INT, name TEXT) ' );
667- $ this ->assertSame ( null , $ this ->getAutoIncrement ( 'plain ' ) );
681+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 'plain' " );
682+ $ this ->assertSame ( null , $ result [0 ]->Auto_increment );
668683
669684 // A fresh AUTO_INCREMENT table reports 1.
670685 $ this ->assertQuery ( 'CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
671- $ this ->assertSame ( '1 ' , $ this ->getAutoIncrement ( 't ' ) );
686+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
687+ $ this ->assertSame ( '1 ' , $ result [0 ]->Auto_increment );
672688
673- // After inserts, Auto_increment is the next value .
689+ // After inserts, the sequence advances .
674690 $ this ->assertQuery ( "INSERT INTO t (name) VALUES ('a'), ('b'), ('c') " );
675- $ this ->assertSame ( '4 ' , $ this ->getAutoIncrement ( 't ' ) );
676-
677- // DELETE must preserve the counter, matching InnoDB behavior.
678- $ this ->assertQuery ( 'DELETE FROM t WHERE id = 3 ' );
679- $ this ->assertSame ( '4 ' , $ this ->getAutoIncrement ( 't ' ) );
691+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
692+ $ this ->assertSame ( '4 ' , $ result [0 ]->Auto_increment );
680693
681- // DELETE of all rows still preserves the counter.
694+ // DELETE preserves the counter.
682695 $ this ->assertQuery ( 'DELETE FROM t ' );
683- $ this ->assertSame ( '4 ' , $ this ->getAutoIncrement ( 't ' ) );
696+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
697+ $ this ->assertSame ( '4 ' , $ result [0 ]->Auto_increment );
684698
685699 // TRUNCATE resets the counter.
686700 $ this ->assertQuery ( 'TRUNCATE TABLE t ' );
687- $ this ->assertSame ( '1 ' , $ this ->getAutoIncrement ( 't ' ) );
701+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
702+ $ this ->assertSame ( '1 ' , $ result [0 ]->Auto_increment );
688703 }
689704
690- public function testShowTableStatusFilterByAutoIncrement () {
705+ public function testShowTableStatusFilterByAutoIncrement (): void {
691706 $ this ->assertQuery ( 'CREATE TABLE low (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
692707 $ this ->assertQuery ( 'CREATE TABLE high (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
693708 $ this ->assertQuery ( 'CREATE TABLE plain (id INT, name TEXT) ' );
694709 $ this ->assertQuery ( "INSERT INTO low (name) VALUES ('a') " );
695710 $ this ->assertQuery ( "INSERT INTO high (name) VALUES ('a'), ('b'), ('c'), ('d'), ('e') " );
696711
697- // WHERE must filter on the computed Auto_increment alias, not on the
698- // always-NULL underlying info_schema column.
699712 $ result = $ this ->assertQuery ( 'SHOW TABLE STATUS WHERE `Auto_increment` > 3 ' );
700713 $ this ->assertCount ( 1 , $ result );
701714 $ this ->assertSame ( 'high ' , $ result [0 ]->Name );
@@ -706,78 +719,137 @@ public function testShowTableStatusFilterByAutoIncrement() {
706719 }
707720
708721 public function testShowCreateTableAutoIncrement (): void {
709- // No AUTO_INCREMENT=N on a non-AI table.
722+ // No AUTO_INCREMENT=N on a non-AUTO_INCREMENT table.
710723 $ this ->assertQuery ( 'CREATE TABLE plain (id INT, name TEXT) ' );
711- $ this ->assertStringNotContainsString (
712- 'AUTO_INCREMENT= ' ,
713- $ this ->getCreateTable ( 'plain ' )
714- );
724+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE plain ' );
725+ $ this ->assertStringNotContainsString ( 'AUTO_INCREMENT= ' , $ result [0 ]->{'Create Table ' } );
715726
716- // No AUTO_INCREMENT=N on a fresh AI table (counter has not advanced).
727+ // No AUTO_INCREMENT=N on a fresh AUTO_INCREMENT table (sequence not advanced).
717728 $ this ->assertQuery ( 'CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
718- $ this ->assertStringNotContainsString (
719- 'AUTO_INCREMENT= ' ,
720- $ this ->getCreateTable ( 't ' )
721- );
729+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
730+ $ this ->assertStringNotContainsString ( 'AUTO_INCREMENT= ' , $ result [0 ]->{'Create Table ' } );
722731
723- // After inserts, AUTO_INCREMENT=<next value> is emitted .
732+ // After inserts, the sequence advances .
724733 $ this ->assertQuery ( "INSERT INTO t (name) VALUES ('a'), ('b'), ('c') " );
725- $ this ->assertStringContainsString (
726- 'AUTO_INCREMENT=4 ' ,
727- $ this ->getCreateTable ( 't ' )
728- );
734+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
735+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=4 ' , $ result [0 ]->{'Create Table ' } );
729736
730737 // DELETE preserves the counter.
731738 $ this ->assertQuery ( 'DELETE FROM t ' );
732- $ this ->assertStringContainsString (
733- 'AUTO_INCREMENT=4 ' ,
734- $ this ->getCreateTable ( 't ' )
735- );
739+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
740+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=4 ' , $ result [0 ]->{'Create Table ' } );
736741
737- // TRUNCATE resets the counter; AUTO_INCREMENT=N is omitted again .
742+ // TRUNCATE resets the counter.
738743 $ this ->assertQuery ( 'TRUNCATE TABLE t ' );
739- $ this ->assertStringNotContainsString (
740- 'AUTO_INCREMENT= ' ,
741- $ this ->getCreateTable ( 't ' )
744+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
745+ $ this ->assertStringNotContainsString ( 'AUTO_INCREMENT= ' , $ result [0 ]->{'Create Table ' } );
746+ }
747+
748+
749+ public function testCreateTableSetAutoIncrement (): void {
750+ $ this ->assertQuery (
751+ 'CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) AUTO_INCREMENT=100 '
742752 );
753+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
754+ $ this ->assertSame ( '100 ' , $ result [0 ]->Auto_increment );
755+
756+ // INSERT advances the sequence.
757+ $ this ->assertQuery ( "INSERT INTO t (name) VALUES ('a') " );
758+ $ this ->assertSame ( '100 ' , $ this ->assertQuery ( 'SELECT id FROM t ' )[0 ]->id );
759+
760+ // SHOW TABLE STATUS
761+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
762+ $ this ->assertSame ( '101 ' , $ result [0 ]->Auto_increment );
763+
764+ // SHOW CREATE TABLE
765+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
766+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=101 ' , $ result [0 ]->{'Create Table ' } );
767+
768+ // Without an AUTO_INCREMENT column, the option is ignored.
769+ $ this ->assertQuery ( 'CREATE TABLE plain (id INT, name TEXT) AUTO_INCREMENT=500 ' );
770+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 'plain' " );
771+ $ this ->assertSame ( null , $ result [0 ]->Auto_increment );
743772 }
744773
745- public function testShowCreateTableAutoIncrementOnTemporaryTable (): void {
746- // Temporary tables live in SQLite's `temp` schema with their own
747- // `sqlite_sequence`. Make sure the counter is read from the right one
748- // even when a persistent AI table in `main` might shadow it.
774+ public function testAlterTableSetAutoIncrement (): void {
775+ $ this ->assertQuery ( 'CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
776+
777+ // Set the sequence value on an empty table.
778+ $ this ->assertQuery ( 'ALTER TABLE t AUTO_INCREMENT = 50 ' );
779+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
780+ $ this ->assertSame ( '50 ' , $ result [0 ]->Auto_increment );
781+
782+ // INSERT advances the sequence.
783+ $ this ->assertQuery ( "INSERT INTO t (name) VALUES ('a') " );
784+ $ this ->assertSame ( '50 ' , $ this ->assertQuery ( 'SELECT id FROM t ' )[0 ]->id );
785+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
786+ $ this ->assertSame ( '51 ' , $ result [0 ]->Auto_increment );
787+
788+ // Update the sequence value.
789+ $ this ->assertQuery ( 'ALTER TABLE t AUTO_INCREMENT = 200 ' );
790+
791+ // SHOW TABLE STATUS
792+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
793+ $ this ->assertSame ( '200 ' , $ result [0 ]->Auto_increment );
794+
795+ // SHOW CREATE TABLE
796+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
797+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=200 ' , $ result [0 ]->{'Create Table ' } );
798+
799+ // Lowering the counter at or below MAX(id) clamps to MAX(id) + 1.
800+ $ this ->assertQuery ( 'ALTER TABLE t AUTO_INCREMENT = 1 ' );
801+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 't' " );
802+ $ this ->assertSame ( '51 ' , $ result [0 ]->Auto_increment );
803+
804+ // Without an AUTO_INCREMENT column, the option is ignored.
805+ $ this ->assertQuery ( 'CREATE TABLE plain (id INT, name TEXT) AUTO_INCREMENT=500 ' );
806+ $ result = $ this ->assertQuery ( "SHOW TABLE STATUS LIKE 'plain' " );
807+ $ this ->assertSame ( null , $ result [0 ]->Auto_increment );
808+ }
809+
810+ public function testTemporaryTableAutoIncrement (): void {
811+ /*
812+ * Temporary tables live in SQLite's "temp" schema with their own
813+ * sqlite_sequence, independent of the persistent one in "main".
814+ * SHOW TABLE STATUS and information_schema.tables list only persistent
815+ * tables, so the temporary sequence is verified through SHOW CREATE
816+ * TABLE and the values produced by the next INSERT.
817+ */
749818 $ this ->assertQuery ( 'CREATE TABLE main_tbl (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
750819 $ this ->assertQuery ( "INSERT INTO main_tbl (name) VALUES ('m') " );
751820
821+ // A fresh temp AUTO_INCREMENT table has no AUTO_INCREMENT=N in SHOW CREATE TABLE.
752822 $ this ->assertQuery ( 'CREATE TEMPORARY TABLE tmp (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) ' );
753- $ this ->assertStringNotContainsString (
754- 'AUTO_INCREMENT= ' ,
755- $ this ->getCreateTable ( 'tmp ' )
756- );
823+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE tmp ' );
824+ $ this ->assertStringNotContainsString ( 'AUTO_INCREMENT= ' , $ result [0 ]->{'Create Table ' } );
757825
826+ // After inserts, the temp sequence advances.
758827 $ this ->assertQuery ( "INSERT INTO tmp (name) VALUES ('a'), ('b') " );
759- $ this ->assertStringContainsString (
760- 'AUTO_INCREMENT=3 ' ,
761- $ this ->getCreateTable ( 'tmp ' )
762- );
828+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE tmp ' );
829+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=3 ' , $ result [0 ]->{'Create Table ' } );
763830
764- // The persistent table's counter must remain independent.
765- $ this ->assertStringContainsString (
766- 'AUTO_INCREMENT=2 ' ,
767- $ this ->getCreateTable ( 'main_tbl ' )
768- );
769- }
831+ // ALTER TABLE AUTO_INCREMENT = N updates the temp sequence, and the
832+ // new value is used by the next insert.
833+ $ this ->assertQuery ( 'ALTER TABLE tmp AUTO_INCREMENT = 77 ' );
834+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE tmp ' );
835+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=77 ' , $ result [0 ]->{'Create Table ' } );
770836
771- private function getAutoIncrement ( string $ table_name ): ?string {
772- $ result = $ this ->assertQuery (
773- sprintf ( "SHOW TABLE STATUS LIKE '%s' " , $ table_name )
837+ $ this ->assertQuery ( "INSERT INTO tmp (name) VALUES ('x') " );
838+ $ this ->assertSame ( '77 ' , $ this ->assertQuery ( "SELECT id FROM tmp WHERE name = 'x' " )[0 ]->id );
839+
840+ // CREATE TEMPORARY TABLE ... AUTO_INCREMENT = N seeds the temp sequence.
841+ $ this ->assertQuery (
842+ 'CREATE TEMPORARY TABLE tmp2 (id INT AUTO_INCREMENT PRIMARY KEY, name TEXT) AUTO_INCREMENT=500 '
774843 );
775- return $ result [0 ]->Auto_increment ;
776- }
844+ $ result = $ this ->assertQuery ( 'SHOW CREATE TABLE tmp2 ' );
845+ $ this ->assertStringContainsString ( 'AUTO_INCREMENT=500 ' , $ result [0 ]->{'Create Table ' } );
846+
847+ $ this ->assertQuery ( "INSERT INTO tmp2 (name) VALUES ('x') " );
848+ $ this ->assertSame ( '500 ' , $ this ->assertQuery ( 'SELECT id FROM tmp2 ' )[0 ]->id );
777849
778- private function getCreateTable ( string $ table_name ): string {
779- $ result = $ this ->assertQuery ( sprintf ( ' SHOW CREATE TABLE %s ' , $ table_name ) );
780- return $ result [0 ]->{ ' Create Table ' } ;
850+ // The persistent table's sequence must remain unaffected throughout.
851+ $ result = $ this ->assertQuery ( " SHOW TABLE STATUS LIKE 'main_tbl' " );
852+ $ this -> assertSame ( ' 2 ' , $ result [0 ]->Auto_increment ) ;
781853 }
782854
783855 public function testShowFullColumns (): void {
0 commit comments