Skip to content
This repository was archived by the owner on Jun 2, 2025. It is now read-only.

Commit a2ea9f8

Browse files
authored
Information schema cleanup and improvements (#49)
The information schema builder requires a few small touches for the new driver release: - [X] It creates some tables that we don't support yet — let's remove those queries. - [X] It doesn't maintain the `table_constraints` table. This table will be needed in the future, and since it also store some information about primary and unique constraints, let's store it now, so we don't have to backfill it with a migration later on. - [X] Make sure identifiers are case-insensitive - [X] Verify index and constraint naming — e.g., what happens when both constraint name and index name are specified, and how duplicate names are handled.
1 parent 5652edb commit a2ea9f8

File tree

5 files changed

+1057
-250
lines changed

5 files changed

+1057
-250
lines changed

tests/WP_SQLite_Driver_Metadata_Tests.php

Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,358 @@ public function testBogusQuery() {
458458
'SELECT 1, BOGUS(1) FROM bogus;'
459459
);
460460
}
461+
462+
public function testInformationSchemaTableConstraintsCreateTable(): void {
463+
$this->assertQuery(
464+
'CREATE TABLE t (
465+
a INT PRIMARY KEY,
466+
b INT UNIQUE,
467+
c INT,
468+
d INT,
469+
CONSTRAINT unique_b_c UNIQUE (b, c),
470+
INDEX inex_c_d (c, d)
471+
)'
472+
);
473+
474+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
475+
$this->assertEquals(
476+
array(
477+
(object) array(
478+
'CONSTRAINT_CATALOG' => 'def',
479+
'CONSTRAINT_SCHEMA' => 'wp',
480+
'CONSTRAINT_NAME' => 'PRIMARY',
481+
'TABLE_SCHEMA' => 'wp',
482+
'TABLE_NAME' => 't',
483+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
484+
'ENFORCED' => 'YES',
485+
),
486+
(object) array(
487+
'CONSTRAINT_CATALOG' => 'def',
488+
'CONSTRAINT_SCHEMA' => 'wp',
489+
'CONSTRAINT_NAME' => 'b',
490+
'TABLE_SCHEMA' => 'wp',
491+
'TABLE_NAME' => 't',
492+
'CONSTRAINT_TYPE' => 'UNIQUE',
493+
'ENFORCED' => 'YES',
494+
),
495+
(object) array(
496+
'CONSTRAINT_CATALOG' => 'def',
497+
'CONSTRAINT_SCHEMA' => 'wp',
498+
'CONSTRAINT_NAME' => 'unique_b_c',
499+
'TABLE_SCHEMA' => 'wp',
500+
'TABLE_NAME' => 't',
501+
'CONSTRAINT_TYPE' => 'UNIQUE',
502+
'ENFORCED' => 'YES',
503+
),
504+
),
505+
$result
506+
);
507+
}
508+
509+
public function testInformationSchemaTableConstraintsDropTable(): void {
510+
$this->assertQuery( 'CREATE TABLE t (a INT PRIMARY KEY, b INT UNIQUE)' );
511+
$this->assertQuery( 'DROP TABLE t' );
512+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
513+
$this->assertEquals( array(), $result );
514+
}
515+
516+
public function testInformationSchemaTableConstraintsAddColumn(): void {
517+
$this->assertQuery(
518+
'CREATE TABLE t ( a INT )'
519+
);
520+
521+
// Add a column with a primary key constraint.
522+
$this->assertQuery( 'ALTER TABLE t ADD COLUMN b INT PRIMARY KEY' );
523+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
524+
$this->assertEquals(
525+
array(
526+
(object) array(
527+
'CONSTRAINT_CATALOG' => 'def',
528+
'CONSTRAINT_SCHEMA' => 'wp',
529+
'CONSTRAINT_NAME' => 'PRIMARY',
530+
'TABLE_SCHEMA' => 'wp',
531+
'TABLE_NAME' => 't',
532+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
533+
'ENFORCED' => 'YES',
534+
),
535+
),
536+
$result
537+
);
538+
539+
$this->assertQuery( 'ALTER TABLE t ADD COLUMN c INT UNIQUE' );
540+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
541+
$this->assertEquals(
542+
array(
543+
(object) array(
544+
'CONSTRAINT_CATALOG' => 'def',
545+
'CONSTRAINT_SCHEMA' => 'wp',
546+
'CONSTRAINT_NAME' => 'PRIMARY',
547+
'TABLE_SCHEMA' => 'wp',
548+
'TABLE_NAME' => 't',
549+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
550+
'ENFORCED' => 'YES',
551+
),
552+
(object) array(
553+
'CONSTRAINT_CATALOG' => 'def',
554+
'CONSTRAINT_SCHEMA' => 'wp',
555+
'CONSTRAINT_NAME' => 'c',
556+
'TABLE_SCHEMA' => 'wp',
557+
'TABLE_NAME' => 't',
558+
'CONSTRAINT_TYPE' => 'UNIQUE',
559+
'ENFORCED' => 'YES',
560+
),
561+
),
562+
$result
563+
);
564+
}
565+
566+
public function testInformationSchemaTableConstraintsChangeColumn(): void {
567+
$this->assertQuery( 'CREATE TABLE t (a INT, b INT)' );
568+
569+
// Add a primary key constraint.
570+
$this->assertQuery( 'ALTER TABLE t CHANGE COLUMN a a INT PRIMARY KEY' );
571+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
572+
$this->assertEquals(
573+
array(
574+
(object) array(
575+
'CONSTRAINT_CATALOG' => 'def',
576+
'CONSTRAINT_SCHEMA' => 'wp',
577+
'CONSTRAINT_NAME' => 'PRIMARY',
578+
'TABLE_SCHEMA' => 'wp',
579+
'TABLE_NAME' => 't',
580+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
581+
'ENFORCED' => 'YES',
582+
),
583+
),
584+
$result
585+
);
586+
587+
// Add a unique constraint.
588+
$this->assertQuery( 'ALTER TABLE t MODIFY COLUMN b INT UNIQUE' );
589+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
590+
$this->assertEquals(
591+
array(
592+
(object) array(
593+
'CONSTRAINT_CATALOG' => 'def',
594+
'CONSTRAINT_SCHEMA' => 'wp',
595+
'CONSTRAINT_NAME' => 'PRIMARY',
596+
'TABLE_SCHEMA' => 'wp',
597+
'TABLE_NAME' => 't',
598+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
599+
'ENFORCED' => 'YES',
600+
),
601+
(object) array(
602+
'CONSTRAINT_CATALOG' => 'def',
603+
'CONSTRAINT_SCHEMA' => 'wp',
604+
'CONSTRAINT_NAME' => 'b',
605+
'TABLE_SCHEMA' => 'wp',
606+
'TABLE_NAME' => 't',
607+
'CONSTRAINT_TYPE' => 'UNIQUE',
608+
'ENFORCED' => 'YES',
609+
),
610+
),
611+
$result
612+
);
613+
}
614+
615+
public function testInformationSchemaTableConstraintsDropColumn(): void {
616+
$this->assertQuery(
617+
'CREATE TABLE t (
618+
id INT,
619+
a INT,
620+
b INT,
621+
c INT,
622+
CONSTRAINT c_primary PRIMARY KEY (a, b),
623+
CONSTRAINT c_unique UNIQUE (b, c),
624+
INDEX id (a, b, c)
625+
)'
626+
);
627+
628+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
629+
$this->assertEquals(
630+
array(
631+
(object) array(
632+
'CONSTRAINT_CATALOG' => 'def',
633+
'CONSTRAINT_SCHEMA' => 'wp',
634+
'CONSTRAINT_NAME' => 'PRIMARY',
635+
'TABLE_SCHEMA' => 'wp',
636+
'TABLE_NAME' => 't',
637+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
638+
'ENFORCED' => 'YES',
639+
),
640+
(object) array(
641+
'CONSTRAINT_CATALOG' => 'def',
642+
'CONSTRAINT_SCHEMA' => 'wp',
643+
'CONSTRAINT_NAME' => 'c_unique',
644+
'TABLE_SCHEMA' => 'wp',
645+
'TABLE_NAME' => 't',
646+
'CONSTRAINT_TYPE' => 'UNIQUE',
647+
'ENFORCED' => 'YES',
648+
),
649+
),
650+
$result
651+
);
652+
653+
// Drop column "b" - all constraints will remain.
654+
$this->assertQuery( 'ALTER TABLE t DROP COLUMN b' );
655+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
656+
$this->assertEquals(
657+
array(
658+
(object) array(
659+
'CONSTRAINT_CATALOG' => 'def',
660+
'CONSTRAINT_SCHEMA' => 'wp',
661+
'CONSTRAINT_NAME' => 'PRIMARY',
662+
'TABLE_SCHEMA' => 'wp',
663+
'TABLE_NAME' => 't',
664+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
665+
'ENFORCED' => 'YES',
666+
),
667+
(object) array(
668+
'CONSTRAINT_CATALOG' => 'def',
669+
'CONSTRAINT_SCHEMA' => 'wp',
670+
'CONSTRAINT_NAME' => 'c_unique',
671+
'TABLE_SCHEMA' => 'wp',
672+
'TABLE_NAME' => 't',
673+
'CONSTRAINT_TYPE' => 'UNIQUE',
674+
'ENFORCED' => 'YES',
675+
),
676+
),
677+
$result
678+
);
679+
680+
// Drop column "c" - the unique constraint will be removed.
681+
$this->assertQuery( 'ALTER TABLE t DROP COLUMN c' );
682+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
683+
$this->assertEquals(
684+
array(
685+
(object) array(
686+
'CONSTRAINT_CATALOG' => 'def',
687+
'CONSTRAINT_SCHEMA' => 'wp',
688+
'CONSTRAINT_NAME' => 'PRIMARY',
689+
'TABLE_SCHEMA' => 'wp',
690+
'TABLE_NAME' => 't',
691+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
692+
'ENFORCED' => 'YES',
693+
),
694+
),
695+
$result
696+
);
697+
698+
// Drop column "a" - the primary key will be removed.
699+
$this->assertQuery( 'ALTER TABLE t DROP COLUMN a' );
700+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
701+
$this->assertEquals( array(), $result );
702+
}
703+
704+
public function testInformationSchemaTableConstraintsAddConstraint(): void {
705+
$this->assertQuery( 'CREATE TABLE t (a INT, b INT)' );
706+
707+
// Add a primary key constraint.
708+
$this->assertQuery( 'ALTER TABLE t ADD CONSTRAINT primary_key_a PRIMARY KEY (a)' );
709+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
710+
$this->assertEquals(
711+
array(
712+
(object) array(
713+
'CONSTRAINT_CATALOG' => 'def',
714+
'CONSTRAINT_SCHEMA' => 'wp',
715+
'CONSTRAINT_NAME' => 'PRIMARY',
716+
'TABLE_SCHEMA' => 'wp',
717+
'TABLE_NAME' => 't',
718+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
719+
'ENFORCED' => 'YES',
720+
),
721+
),
722+
$result
723+
);
724+
725+
// Add a unique constraint.
726+
$this->assertQuery( 'ALTER TABLE t ADD CONSTRAINT unique_b UNIQUE (b)' );
727+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
728+
$this->assertEquals(
729+
array(
730+
(object) array(
731+
'CONSTRAINT_CATALOG' => 'def',
732+
'CONSTRAINT_SCHEMA' => 'wp',
733+
'CONSTRAINT_NAME' => 'PRIMARY',
734+
'TABLE_SCHEMA' => 'wp',
735+
'TABLE_NAME' => 't',
736+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
737+
'ENFORCED' => 'YES',
738+
),
739+
(object) array(
740+
'CONSTRAINT_CATALOG' => 'def',
741+
'CONSTRAINT_SCHEMA' => 'wp',
742+
'CONSTRAINT_NAME' => 'unique_b',
743+
'TABLE_SCHEMA' => 'wp',
744+
'TABLE_NAME' => 't',
745+
'CONSTRAINT_TYPE' => 'UNIQUE',
746+
'ENFORCED' => 'YES',
747+
),
748+
),
749+
$result
750+
);
751+
752+
// Add a unique constraint with a composite key.
753+
$this->assertQuery( 'ALTER TABLE t ADD CONSTRAINT unique_a_b UNIQUE (a, b)' );
754+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
755+
$this->assertEquals(
756+
array(
757+
(object) array(
758+
'CONSTRAINT_CATALOG' => 'def',
759+
'CONSTRAINT_SCHEMA' => 'wp',
760+
'CONSTRAINT_NAME' => 'PRIMARY',
761+
'TABLE_SCHEMA' => 'wp',
762+
'TABLE_NAME' => 't',
763+
'CONSTRAINT_TYPE' => 'PRIMARY KEY',
764+
'ENFORCED' => 'YES',
765+
),
766+
(object) array(
767+
'CONSTRAINT_CATALOG' => 'def',
768+
'CONSTRAINT_SCHEMA' => 'wp',
769+
'CONSTRAINT_NAME' => 'unique_b',
770+
'TABLE_SCHEMA' => 'wp',
771+
'TABLE_NAME' => 't',
772+
'CONSTRAINT_TYPE' => 'UNIQUE',
773+
'ENFORCED' => 'YES',
774+
),
775+
(object) array(
776+
'CONSTRAINT_CATALOG' => 'def',
777+
'CONSTRAINT_SCHEMA' => 'wp',
778+
'CONSTRAINT_NAME' => 'unique_a_b',
779+
'TABLE_SCHEMA' => 'wp',
780+
'TABLE_NAME' => 't',
781+
'CONSTRAINT_TYPE' => 'UNIQUE',
782+
'ENFORCED' => 'YES',
783+
),
784+
),
785+
$result
786+
);
787+
}
788+
789+
public function testInformationSchemaTableConstraintsDropIndex(): void {
790+
$this->assertQuery( 'CREATE TABLE t (a INT PRIMARY KEY, b INT UNIQUE)' );
791+
792+
// Drop the primary key index.
793+
$this->assertQuery( 'ALTER TABLE t DROP INDEX `PRIMARY`' );
794+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
795+
$this->assertEquals(
796+
array(
797+
(object) array(
798+
'CONSTRAINT_CATALOG' => 'def',
799+
'CONSTRAINT_SCHEMA' => 'wp',
800+
'CONSTRAINT_NAME' => 'b',
801+
'TABLE_SCHEMA' => 'wp',
802+
'TABLE_NAME' => 't',
803+
'CONSTRAINT_TYPE' => 'UNIQUE',
804+
'ENFORCED' => 'YES',
805+
),
806+
),
807+
$result
808+
);
809+
810+
// Drop the unique index.
811+
$this->assertQuery( 'ALTER TABLE t DROP INDEX b' );
812+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
813+
$this->assertEquals( array(), $result );
814+
}
461815
}

0 commit comments

Comments
 (0)