diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-10-16 08:44:55 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-10-16 08:44:55 +0100 |
| commit | 77c708cbb7a4fb49db50a8917bdcdd777eff6ccb (patch) | |
| tree | 4aeb55e2ff372c980e3893302a0f0166f656d67c /src/main/java | |
| parent | 8fe3ffe8c7aad4c3270b889bce0efaf4ab912157 (diff) | |
Check primary key field exists
Diffstat (limited to 'src/main/java')
4 files changed, 47 insertions, 7 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java index 315aeef..9a9f98b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java @@ -8,18 +8,18 @@ package org.zwobble.hobgoblin.compiler.ast.typed; public record TypedTableDefinitionNode( String name, org.zwobble.hobgoblin.compiler.types.StructType rowType, - String primaryKey, + org.zwobble.hobgoblin.compiler.types.Field primaryKey, org.zwobble.hobgoblin.compiler.ast.DocComment docComment, org.zwobble.hobgoblin.compiler.sources.Source source ) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode { public static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.types.HobgoblinNativeTypes.arbitraryStructType(), "", org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource()); + return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.types.HobgoblinNativeTypes.arbitraryStructType(), org.zwobble.hobgoblin.compiler.types.HobgoblinNativeTypes.arbitraryField(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource()); } public record Builder( String name, org.zwobble.hobgoblin.compiler.types.StructType rowType, - String primaryKey, + org.zwobble.hobgoblin.compiler.types.Field primaryKey, org.zwobble.hobgoblin.compiler.ast.DocComment docComment, org.zwobble.hobgoblin.compiler.sources.Source source ) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode.Builder { @@ -35,7 +35,7 @@ public record TypedTableDefinitionNode( return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source); } - public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withPrimaryKey(String primaryKey) { + public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withPrimaryKey(org.zwobble.hobgoblin.compiler.types.Field primaryKey) { return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java index 211726b..c8dfc05 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -5,6 +5,7 @@ import org.zwobble.hobgoblin.compiler.ast.untyped.*; import org.zwobble.hobgoblin.compiler.builtins.NativeTypes; import org.zwobble.hobgoblin.compiler.sources.Source; import org.zwobble.hobgoblin.compiler.typechecker.errors.*; +import org.zwobble.hobgoblin.compiler.typechecker.errors.NoSuchFieldError; import org.zwobble.hobgoblin.compiler.types.*; import java.util.ArrayList; @@ -470,18 +471,27 @@ public class TypeChecker { ) { var rowTypeTypedNode = typeCheckMetaType(untyped.rowType(), context); - if (!(rowTypeTypedNode.value() instanceof StructType rowType)) { + // TODO: allow constructed struct types + if (!(rowTypeTypedNode.value() instanceof SimpleStructType rowType)) { throw new TableRowTypeMustBeStructError( rowTypeTypedNode.value(), rowTypeTypedNode.source() ); } + var fields = context.fieldsOf(rowType).orElse(List.of()); + var primaryKeyField = fields.stream() + .filter(field -> field.name().equals(untyped.primaryKey())) + .findFirst(); + if (primaryKeyField.isEmpty()) { + // TODO: more precise source. + throw new NoSuchFieldError(rowType, untyped.primaryKey(), untyped.source()); + } + return new TypedTableDefinitionNode( untyped.name(), rowType, - // TODO: check primary key is valid. - untyped.primaryKey(), + primaryKeyField.get(), untyped.docComment(), untyped.source() ); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchFieldError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchFieldError.java new file mode 100644 index 0000000..635ea6f --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchFieldError.java @@ -0,0 +1,24 @@ +package org.zwobble.hobgoblin.compiler.typechecker.errors; + +import org.zwobble.hobgoblin.compiler.errors.SourceError; +import org.zwobble.hobgoblin.compiler.sources.Source; +import org.zwobble.hobgoblin.compiler.types.Type; + +public class NoSuchFieldError extends SourceError { + private final Type type; + private final String fieldName; + + public NoSuchFieldError(Type type, String fieldName, Source source) { + super(type.describe() + " does not have a field named " + fieldName, source); + this.type = type; + this.fieldName = fieldName; + } + + public Type type() { + return type; + } + + public String fieldName() { + return fieldName; + } +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java index 37e6935..96efbd2 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java @@ -1,5 +1,7 @@ package org.zwobble.hobgoblin.compiler.types; +import org.zwobble.hobgoblin.compiler.sources.NullSource; + import java.util.function.Supplier; public class HobgoblinNativeTypes { @@ -34,4 +36,8 @@ public class HobgoblinNativeTypes { public static <T extends ConstructibleType> TypeOrConstructor<T> arbitraryTypeOrConstructor(Supplier<T> type) { return TypeOrConstructor.type(type.get()); } + + public static Field arbitraryField() { + return new Field("", arbitraryType(), NullSource.INSTANCE); + } } |
