1818import sqlancer .QueryAdapter ;
1919import sqlancer .Randomly ;
2020import sqlancer .StateToReproduce .SQLite3StateToReproduce ;
21+ import sqlancer .schema .AbstractTable ;
22+ import sqlancer .schema .AbstractTableColumn ;
23+ import sqlancer .schema .TableIndex ;
2124import sqlancer .sqlite3 .SQLite3Errors ;
2225import sqlancer .sqlite3 .SQLite3ToStringVisitor ;
2326import sqlancer .sqlite3 .ast .SQLite3Constant ;
@@ -49,15 +52,12 @@ public SQLite3Table getRandomTableOrBailout() {
4952 }
5053 }
5154
52- public static class SQLite3Column implements Comparable < SQLite3Column > {
55+ public static class SQLite3Column extends AbstractTableColumn < SQLite3Table , SQLite3DataType > {
5356
54- private final String name ;
55- private final SQLite3DataType columnType ;
56- private final boolean isPrimaryKey ;
5757 private final boolean isInteger ; // "INTEGER" type, not "INT"
58- private SQLite3Table table ;
5958 private final SQLite3CollateSequence collate ;
6059 private boolean generated ;
60+ private boolean isPrimaryKey ;
6161
6262 public enum SQLite3CollateSequence {
6363 NOCASE , RTRIM , BINARY ;
@@ -69,8 +69,7 @@ public static SQLite3CollateSequence random() {
6969
7070 public SQLite3Column (String name , SQLite3DataType columnType , boolean isInteger , boolean isPrimaryKey ,
7171 SQLite3CollateSequence collate ) {
72- this .name = name ;
73- this .columnType = columnType ;
72+ super (name , null , columnType );
7473 this .isInteger = isInteger ;
7574 this .isPrimaryKey = isPrimaryKey ;
7675 this .collate = collate ;
@@ -84,44 +83,12 @@ public SQLite3Column(String rowId, SQLite3DataType columnType2, boolean contains
8483 this .generated = generated ;
8584 }
8685
87- @ Override
88- public String toString () {
89- return String .format ("%s.%s: %s" , table .getName (), name , columnType );
90- }
91-
92- @ Override
93- public int hashCode () {
94- return name .hashCode () + 11 * columnType .hashCode ();
95- }
96-
97- @ Override
98- public boolean equals (Object obj ) {
99- if (!(obj instanceof SQLite3Column )) {
100- return false ;
101- } else {
102- SQLite3Column c = (SQLite3Column ) obj ;
103- return table .getName ().contentEquals (getName ()) && name .equals (c .name );
104- }
105- }
106-
107- public String getName () {
108- return name ;
109- }
110-
111- public String getFullQualifiedName () {
112- return table .getName () + "." + getName ();
113- }
114-
115- public SQLite3DataType getColumnType () {
116- return columnType ;
117- }
118-
11986 public boolean isPrimaryKey () {
12087 return isPrimaryKey ;
12188 }
12289
12390 public boolean isOnlyPrimaryKey () {
124- return isPrimaryKey && table .getColumns ().stream ().filter (c -> c .isPrimaryKey ()).count () == 1 ;
91+ return isPrimaryKey && getTable () .getColumns ().stream ().filter (c -> c .isPrimaryKey ()).count () == 1 ;
12592 }
12693
12794 // see https://www.sqlite.org/lang_createtable.html#rowid
@@ -131,24 +98,7 @@ public boolean isOnlyPrimaryKey() {
13198 * column is known as an INTEGER PRIMARY KEY.
13299 */
133100 public boolean isIntegerPrimaryKey () {
134- return isInteger && isOnlyPrimaryKey () && !table .hasWithoutRowid ();
135- }
136-
137- public void setTable (SQLite3Table table ) {
138- this .table = table ;
139- }
140-
141- public SQLite3Table getTable () {
142- return table ;
143- }
144-
145- @ Override
146- public int compareTo (SQLite3Column o ) {
147- if (o .getTable ().equals (this .getTable ())) {
148- return name .compareTo (o .getName ());
149- } else {
150- return o .getTable ().compareTo (table );
151- }
101+ return isInteger && isOnlyPrimaryKey () && !getTable ().hasWithoutRowid ();
152102 }
153103
154104 public SQLite3CollateSequence getCollateSequence () {
@@ -265,72 +215,35 @@ public SQLite3RowValue getRandomRowValue(Connection con, SQLite3StateToReproduce
265215
266216 }
267217
268- public static class SQLite3Table implements Comparable <SQLite3Table > {
218+
219+ public static class SQLite3Table extends AbstractTable <SQLite3Column , TableIndex > {
220+ // TODO: why does the SQLite implementation have no table indexes?
269221
270222 public static enum TableKind {
271223 MAIN , TEMP ;
272224 }
273225
274- private final String tableName ;
275- private final List <SQLite3Column > columns ;
276226 private final TableKind tableType ;
277227 private SQLite3Column rowid ;
278228 private boolean withoutRowid ;
279229 private int nrRows ;
280- private boolean isView ;
281230 private boolean isVirtual ;
282231 private boolean isReadOnly ;
283232
284233 public SQLite3Table (String tableName , List <SQLite3Column > columns , TableKind tableType , boolean withoutRowid ,
285234 int nrRows , boolean isView , boolean isVirtual , boolean isReadOnly ) {
286- this . tableName = tableName ;
235+ super ( tableName , columns , Collections . emptyList (), isView ) ;
287236 this .tableType = tableType ;
288237 this .withoutRowid = withoutRowid ;
289- this .isView = isView ;
290238 this .isVirtual = isVirtual ;
291239 this .isReadOnly = isReadOnly ;
292- this .columns = Collections .unmodifiableList (columns );
293240 this .nrRows = nrRows ;
294241 }
295242
296243 public boolean hasWithoutRowid () {
297244 return withoutRowid ;
298245 }
299246
300- @ Override
301- public String toString () {
302- StringBuffer sb = new StringBuffer ();
303- sb .append (tableName + "\n " );
304- for (SQLite3Column c : columns ) {
305- sb .append ("\t " + c + "\n " );
306- }
307- return sb .toString ();
308- }
309-
310- public String getName () {
311- return tableName ;
312- }
313-
314- public List <SQLite3Column > getColumns () {
315- return columns ;
316- }
317-
318- public String getColumnsAsString () {
319- return columns .stream ().map (c -> c .getName ()).collect (Collectors .joining (", " ));
320- }
321-
322- public String getColumnsAsString (Function <SQLite3Column , String > function ) {
323- return columns .stream ().map (function ).collect (Collectors .joining (", " ));
324- }
325-
326- public SQLite3Column getRandomColumn () {
327- return Randomly .fromList (columns );
328- }
329-
330- @ Override
331- public int compareTo (SQLite3Table o ) {
332- return o .getName ().compareTo (tableName );
333- }
334247
335248 public void addRowid (SQLite3Column rowid ) {
336249 this .rowid = rowid ;
@@ -348,10 +261,6 @@ public boolean isVirtual() {
348261 return isVirtual ;
349262 }
350263
351- public List <SQLite3Column > getRandomNonEmptyColumnSubset () {
352- return Randomly .nonEmptySubset (getColumns ());
353- }
354-
355264 public boolean isSystemTable () {
356265 return getName ().startsWith ("sqlit" );
357266 }
@@ -360,10 +269,6 @@ public int getNrRows() {
360269 return nrRows ;
361270 }
362271
363- public boolean isView () {
364- return isView ;
365- }
366-
367272 public boolean isTemp () {
368273 return tableType == TableKind .TEMP ;
369274 }
@@ -693,11 +598,11 @@ public SQLite3Table getRandomTableNoViewNoVirtualTable() {
693598 }
694599
695600 public List <SQLite3Table > getDatabaseTablesWithoutViews () {
696- return databaseTables .stream ().filter (t -> !t .isView ).collect (Collectors .toList ());
601+ return databaseTables .stream ().filter (t -> !t .isView () ).collect (Collectors .toList ());
697602 }
698603
699604 public List <SQLite3Table > getViews () {
700- return databaseTables .stream ().filter (t -> t .isView ).collect (Collectors .toList ());
605+ return databaseTables .stream ().filter (t -> t .isView () ).collect (Collectors .toList ());
701606 }
702607
703608 public SQLite3Table getRandomViewOrBailout () {
@@ -709,7 +614,7 @@ public SQLite3Table getRandomViewOrBailout() {
709614 }
710615
711616 public List <SQLite3Table > getDatabaseTablesWithoutViewsWithoutVirtualTables () {
712- return databaseTables .stream ().filter (t -> !t .isView && !t .isVirtual ).collect (Collectors .toList ());
617+ return databaseTables .stream ().filter (t -> !t .isView () && !t .isVirtual ).collect (Collectors .toList ());
713618 }
714619
715620}
0 commit comments