Skip to content

Commit 39dd489

Browse files
authored
Add support for CHECK constraints (#257)
Implements support for `CHECK` constraints: ```sql CREATE TABLE t ( id INT NOT NULL CHECK (id > 0), name VARCHAR(255) NOT NULL CHECK (name != ''), score DOUBLE NOT NULL CHECK (score > 0 AND score < 100), data JSON CHECK (json_valid(data)), start_timestamp TIMESTAMP NOT NULL, end_timestamp TIMESTAMP NOT NULL, CONSTRAINT c1 CHECK (id < 10), CONSTRAINT c2 CHECK (start_timestamp < end_timestamp), CONSTRAINT c3 CHECK (length(data) < 20) ) ``` This includes support for: 1. `CREATE TABLE` with inline `CHECK (...)` for column definitions. 2. `CREATE TABLE` with `CHECK (...)` and `CONSTRAINT ... CHECK (...)` definitions. 3. `ALTER TABLE ... ADD CHECK (...)` and `ALTER TABLE ... ADD CONSTRAINT ... CHECK (...)` statements. 4. `ALTER TABLE ... DROP CONSTRAINT ...` statements. 5. `ALTER TABLE ... DROP CHECK ...` statements. 6. `CHECK` constraints with the `NOT ENFORCED` clause. Resolves #251.
1 parent 8d63ed0 commit 39dd489

5 files changed

Lines changed: 736 additions & 38 deletions

tests/WP_SQLite_Driver_Metadata_Tests.php

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,4 +1878,221 @@ public function testInformationSchemaAlterTableDropConstraintWithAmbiguousName()
18781878
$this->expectExceptionCode( 'HY000' );
18791879
$this->assertQuery( 'ALTER TABLE t2 DROP CONSTRAINT cnst' );
18801880
}
1881+
1882+
public function testInformationSchemaCheckConstraints(): void {
1883+
$this->assertQuery(
1884+
"CREATE TABLE t (
1885+
id INT NOT NULL CHECK (id > 0),
1886+
name VARCHAR(255) NOT NULL CHECK (name != ''),
1887+
score DOUBLE NOT NULL CHECK (score > 0 AND score < 100),
1888+
data JSON CHECK (json_valid(data)),
1889+
start_timestamp TIMESTAMP NOT NULL,
1890+
end_timestamp TIMESTAMP NOT NULL,
1891+
CONSTRAINT c1 CHECK (id < 10),
1892+
CONSTRAINT c2 CHECK (start_timestamp < end_timestamp),
1893+
CONSTRAINT c3 CHECK (length(data) < 20)
1894+
)"
1895+
);
1896+
1897+
// INFORMATION_SCHEMA.TABLE_CONSTRAINTS
1898+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't' ORDER BY CONSTRAINT_NAME" );
1899+
$this->assertEquals(
1900+
array(
1901+
(object) array(
1902+
'CONSTRAINT_CATALOG' => 'def',
1903+
'CONSTRAINT_SCHEMA' => 'wp',
1904+
'CONSTRAINT_NAME' => 'c1',
1905+
'TABLE_SCHEMA' => 'wp',
1906+
'TABLE_NAME' => 't',
1907+
'CONSTRAINT_TYPE' => 'CHECK',
1908+
'ENFORCED' => 'YES',
1909+
),
1910+
(object) array(
1911+
'CONSTRAINT_CATALOG' => 'def',
1912+
'CONSTRAINT_SCHEMA' => 'wp',
1913+
'CONSTRAINT_NAME' => 'c2',
1914+
'TABLE_SCHEMA' => 'wp',
1915+
'TABLE_NAME' => 't',
1916+
'CONSTRAINT_TYPE' => 'CHECK',
1917+
'ENFORCED' => 'YES',
1918+
),
1919+
(object) array(
1920+
'CONSTRAINT_CATALOG' => 'def',
1921+
'CONSTRAINT_SCHEMA' => 'wp',
1922+
'CONSTRAINT_NAME' => 'c3',
1923+
'TABLE_SCHEMA' => 'wp',
1924+
'TABLE_NAME' => 't',
1925+
'CONSTRAINT_TYPE' => 'CHECK',
1926+
'ENFORCED' => 'YES',
1927+
),
1928+
(object) array(
1929+
'CONSTRAINT_CATALOG' => 'def',
1930+
'CONSTRAINT_SCHEMA' => 'wp',
1931+
'CONSTRAINT_NAME' => 't_chk_1',
1932+
'TABLE_SCHEMA' => 'wp',
1933+
'TABLE_NAME' => 't',
1934+
'CONSTRAINT_TYPE' => 'CHECK',
1935+
'ENFORCED' => 'YES',
1936+
),
1937+
(object) array(
1938+
'CONSTRAINT_CATALOG' => 'def',
1939+
'CONSTRAINT_SCHEMA' => 'wp',
1940+
'CONSTRAINT_NAME' => 't_chk_2',
1941+
'TABLE_SCHEMA' => 'wp',
1942+
'TABLE_NAME' => 't',
1943+
'CONSTRAINT_TYPE' => 'CHECK',
1944+
'ENFORCED' => 'YES',
1945+
),
1946+
(object) array(
1947+
'CONSTRAINT_CATALOG' => 'def',
1948+
'CONSTRAINT_SCHEMA' => 'wp',
1949+
'CONSTRAINT_NAME' => 't_chk_3',
1950+
'TABLE_SCHEMA' => 'wp',
1951+
'TABLE_NAME' => 't',
1952+
'CONSTRAINT_TYPE' => 'CHECK',
1953+
'ENFORCED' => 'YES',
1954+
),
1955+
(object) array(
1956+
'CONSTRAINT_CATALOG' => 'def',
1957+
'CONSTRAINT_SCHEMA' => 'wp',
1958+
'CONSTRAINT_NAME' => 't_chk_4',
1959+
'TABLE_SCHEMA' => 'wp',
1960+
'TABLE_NAME' => 't',
1961+
'CONSTRAINT_TYPE' => 'CHECK',
1962+
'ENFORCED' => 'YES',
1963+
),
1964+
),
1965+
$result
1966+
);
1967+
1968+
// INFORMATION_SCHEMA.CHECK_CONSTRAINTS
1969+
$result = $this->assertQuery( 'SELECT * FROM information_schema.check_constraints ORDER BY CONSTRAINT_NAME' );
1970+
$this->assertCount( 7, $result );
1971+
1972+
$this->assertEquals(
1973+
array(
1974+
(object) array(
1975+
'CONSTRAINT_CATALOG' => 'def',
1976+
'CONSTRAINT_SCHEMA' => 'wp',
1977+
'CONSTRAINT_NAME' => 'c1',
1978+
'CHECK_CLAUSE' => '( id < 10 )',
1979+
),
1980+
(object) array(
1981+
'CONSTRAINT_CATALOG' => 'def',
1982+
'CONSTRAINT_SCHEMA' => 'wp',
1983+
'CONSTRAINT_NAME' => 'c2',
1984+
'CHECK_CLAUSE' => '( start_timestamp < end_timestamp )',
1985+
),
1986+
(object) array(
1987+
'CONSTRAINT_CATALOG' => 'def',
1988+
'CONSTRAINT_SCHEMA' => 'wp',
1989+
'CONSTRAINT_NAME' => 'c3',
1990+
'CHECK_CLAUSE' => '( length ( data ) < 20 )',
1991+
),
1992+
(object) array(
1993+
'CONSTRAINT_CATALOG' => 'def',
1994+
'CONSTRAINT_SCHEMA' => 'wp',
1995+
'CONSTRAINT_NAME' => 't_chk_1',
1996+
'CHECK_CLAUSE' => '( id > 0 )',
1997+
),
1998+
(object) array(
1999+
'CONSTRAINT_CATALOG' => 'def',
2000+
'CONSTRAINT_SCHEMA' => 'wp',
2001+
'CONSTRAINT_NAME' => 't_chk_2',
2002+
'CHECK_CLAUSE' => "( name != '' )",
2003+
),
2004+
(object) array(
2005+
'CONSTRAINT_CATALOG' => 'def',
2006+
'CONSTRAINT_SCHEMA' => 'wp',
2007+
'CONSTRAINT_NAME' => 't_chk_3',
2008+
'CHECK_CLAUSE' => '( score > 0 AND score < 100 )',
2009+
),
2010+
(object) array(
2011+
'CONSTRAINT_CATALOG' => 'def',
2012+
'CONSTRAINT_SCHEMA' => 'wp',
2013+
'CONSTRAINT_NAME' => 't_chk_4',
2014+
'CHECK_CLAUSE' => '( json_valid ( data ) )',
2015+
),
2016+
),
2017+
$result
2018+
);
2019+
}
2020+
2021+
public function testInformationSchemaAlterTableAddCheckConstraint(): void {
2022+
$this->assertQuery( 'CREATE TABLE t (id INT)' );
2023+
2024+
// ADD CONSTRAINT syntax.
2025+
$this->assertQuery( 'ALTER TABLE t ADD CONSTRAINT c CHECK (id > 0)' );
2026+
2027+
// ADD CHECK syntax.
2028+
$this->assertQuery( 'ALTER TABLE t ADD CHECK (id < 10)' );
2029+
2030+
// INFORMATION_SCHEMA.TABLE_CONSTRAINTS
2031+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't' ORDER BY CONSTRAINT_NAME" );
2032+
$this->assertEquals(
2033+
array(
2034+
(object) array(
2035+
'CONSTRAINT_CATALOG' => 'def',
2036+
'CONSTRAINT_SCHEMA' => 'wp',
2037+
'CONSTRAINT_NAME' => 'c',
2038+
'TABLE_SCHEMA' => 'wp',
2039+
'TABLE_NAME' => 't',
2040+
'CONSTRAINT_TYPE' => 'CHECK',
2041+
'ENFORCED' => 'YES',
2042+
),
2043+
(object) array(
2044+
'CONSTRAINT_CATALOG' => 'def',
2045+
'CONSTRAINT_SCHEMA' => 'wp',
2046+
'CONSTRAINT_NAME' => 't_chk_1',
2047+
'TABLE_SCHEMA' => 'wp',
2048+
'TABLE_NAME' => 't',
2049+
'CONSTRAINT_TYPE' => 'CHECK',
2050+
'ENFORCED' => 'YES',
2051+
),
2052+
),
2053+
$result
2054+
);
2055+
2056+
// INFORMATION_SCHEMA.CHECK_CONSTRAINTS
2057+
$result = $this->assertQuery( 'SELECT * FROM information_schema.check_constraints ORDER BY CONSTRAINT_NAME' );
2058+
$this->assertEquals(
2059+
array(
2060+
(object) array(
2061+
'CONSTRAINT_CATALOG' => 'def',
2062+
'CONSTRAINT_SCHEMA' => 'wp',
2063+
'CONSTRAINT_NAME' => 'c',
2064+
'CHECK_CLAUSE' => '( id > 0 )',
2065+
),
2066+
(object) array(
2067+
'CONSTRAINT_CATALOG' => 'def',
2068+
'CONSTRAINT_SCHEMA' => 'wp',
2069+
'CONSTRAINT_NAME' => 't_chk_1',
2070+
'CHECK_CLAUSE' => '( id < 10 )',
2071+
),
2072+
),
2073+
$result
2074+
);
2075+
}
2076+
2077+
public function testInformationSchemaAlterTableDropCheckConstraint(): void {
2078+
$this->assertQuery( 'CREATE TABLE t (id INT, CONSTRAINT c1 CHECK (id > 0), CONSTRAINT c2 CHECK (id < 10))' );
2079+
2080+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
2081+
$this->assertCount( 2, $result );
2082+
2083+
$result = $this->assertQuery( 'SELECT * FROM information_schema.check_constraints' );
2084+
$this->assertCount( 2, $result );
2085+
2086+
// DROP CONSTRAINT syntax.
2087+
$this->assertQuery( 'ALTER TABLE t DROP CONSTRAINT c1' );
2088+
2089+
// DROP CHECK syntax.
2090+
$this->assertQuery( 'ALTER TABLE t DROP CHECK c2' );
2091+
2092+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
2093+
$this->assertCount( 0, $result );
2094+
2095+
$result = $this->assertQuery( 'SELECT * FROM information_schema.check_constraints' );
2096+
$this->assertCount( 0, $result );
2097+
}
18812098
}

0 commit comments

Comments
 (0)