diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-11-02 18:37:17 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-11-02 18:37:17 +0000 |
| commit | 585728b94ea1037ddb3c009a0ff18ff62a1c3db3 (patch) | |
| tree | 9a22643232a6eb725dba61f41c26ace266854961 /src | |
| parent | b247d99c6950fec45199ff78f8bd16af48d5f96c (diff) | |
Add test around generating SQL SELECT
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java | 20 | ||||
| -rw-r--r-- | src/test/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGeneratorTests.java | 69 |
2 files changed, 83 insertions, 6 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java index 624b3fe..456ffd8 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGenerator.java @@ -1,5 +1,6 @@ package org.zwobble.hobgoblin.compiler.output.generators.sql; +import org.zwobble.hobgoblin.compiler.ast.typed.Relation; import org.zwobble.hobgoblin.compiler.ast.typed.RelationTable; import org.zwobble.hobgoblin.compiler.ast.typed.TypedQueryDefinitionNode; import org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode; @@ -56,7 +57,11 @@ public class SqlGenerator { TypedQueryDefinitionNode queryDefinition, TypesInfo typesInfo ) { - switch (queryDefinition.relation()) { + return generateRelation(queryDefinition.relation(), typesInfo); + } + + SqlSelectStatement generateRelation(Relation relation, TypesInfo typesInfo) { + switch (relation) { case RelationTable relationTable -> { var table = relationTable.table(); var schemaInfo = typesInfo.databaseSchemaInfo(table.databaseSchema()); @@ -73,14 +78,17 @@ public class SqlGenerator { }) .toList(); + // Order by the primary key to ensure stable ordering. + var orderBy = List.of( + new SqlOrderingTerm(new SqlRef( + generateColumnName(tableInfo.primaryKey().name()) + )) + ); + return new SqlSelectStatement( columns, generateTableName(table.name()), - List.of( - new SqlOrderingTerm(new SqlRef( - generateColumnName(tableInfo.primaryKey().name()) - )) - ) + orderBy ); } } diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGeneratorTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGeneratorTests.java new file mode 100644 index 0000000..0438baf --- /dev/null +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/generators/sql/SqlGeneratorTests.java @@ -0,0 +1,69 @@ +package org.zwobble.hobgoblin.compiler.output.generators.sql; + +import org.junit.jupiter.api.Test; +import org.zwobble.hobgoblin.compiler.ast.typed.RelationTable; +import org.zwobble.hobgoblin.compiler.builtins.NativeTypes; +import org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlIdentifier; +import org.zwobble.hobgoblin.compiler.sources.NullSource; +import org.zwobble.hobgoblin.compiler.typechecker.TypesInfoInMemory; +import org.zwobble.hobgoblin.compiler.types.*; +import org.zwobble.hobgoblin.compiler.util.SequencedMaps; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlOrderingTermMatcher.isSqlOrderingTerm; +import static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlRefMatcher.isSqlRef; +import static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlResultColumnMatcher.isSqlResultColumn; +import static org.zwobble.hobgoblin.compiler.output.lang.sql.ast.SqlSelectStatementMatcher.isSqlSelectStatement; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.isSequence; + +public class SqlGeneratorTests { + @Test + public void relationTableIsTranslatedToSelectFromTable() { + var namespaceName = NamespaceName.of("App"); + var databaseSchema = new DatabaseSchema(namespaceName, "blog"); + var table = new Table(databaseSchema, "authors"); + var authorType = new SimpleStructType(namespaceName, "Author"); + var authorIdField = new Field("id", NativeTypes.INT_32, NullSource.INSTANCE); + var authorNameField = new Field("name", NativeTypes.STRING, NullSource.INSTANCE); + + var typesInfo = TypesInfoInMemory.empty(); + var databaseSchemaInfo = new DatabaseSchemaInfo(SequencedMaps.ofEntries( + Map.entry("authors", new TableInfo(table, authorType, authorIdField)) + )); + typesInfo.defineDatabaseSchema(databaseSchema, databaseSchemaInfo); + typesInfo.defineStructType(authorType, Optional.of(List.of(authorIdField, authorNameField))); + + var sqlGenerator = new SqlGenerator(); + + var relation = RelationTable.arbitrary() + .withTable(table) + .build(); + + var statement = sqlGenerator.generateRelation(relation, typesInfo); + + assertThat(statement, isSqlSelectStatement() + .withColumns(isSequence( + isSqlResultColumn() + .withExpression(isSqlRef().withName(equalTo(id("id")))) + .withAlias(equalTo(id("id"))), + isSqlResultColumn() + .withExpression(isSqlRef().withName(equalTo(id("name")))) + .withAlias(equalTo(id("name"))) + )) + .withFrom(equalTo(id("authors"))) + .withOrderBy(isSequence( + isSqlOrderingTerm() + .withExpression(isSqlRef().withName(equalTo(id("id")))) + )) + ); + } + + private SqlIdentifier id(String value) { + return new SqlIdentifier(value); + } +} |
