Skip to content

Wrong column name in predicates with connected fields #512

@micrb

Description

@micrb

Describe the bug

The following statement should translate Post.keys.user to postUserId

Amplify.DataStore.query(Post.self, where: Post.keys.user == Service.shared.userId()

However the following error occurs:

no such column: root.user in "select
  "root"."id" as "id", "root"."createdTimestamp" as "createdTimestamp", "root"."imageUrl" as "imageUrl",
  "root"."text" as "text", "root"."updatedTimestamp" as "updatedTimestamp", "root"."postUserId" as "postUserId",
  "user"."id" as "user.id", "user"."bio" as "user.bio", "user"."createdTimestamp" as "user.createdTimestamp",
  "user"."emailAddress" as "user.emailAddress", "user"."fullName" as "user.fullName", "user"."isEditable" as "user.isEditable",
  "user"."isFollowing" as "user.isFollowing", "user"."profileImageUrl" as "user.profileImageUrl", "user"."updatedTimestamp" as "user.updatedTimestamp"
from Post as root
inner join User as user
  on "user"."id" = "root"."postUserId"
where 1 = 1
  and "root"."user" = ?"
Failed to retrieve posts: DataStoreError: The operation couldn’t be completed. (SQLite.Result error 0.)

Referring to a model

type User @model {
  id: ID!
  fullName: String!
  emailAddress: String
  bio: String
  profileImageUrl: String
  isFollowing: Boolean
  following: [UserFollowing] @connection(name: "UserFollowing")
  followers: [UserFollowers] @connection(name: "UserFollowers")
  isEditable: Boolean
  posts: [Post] @connection(name: "UserPosts")
  createdTimestamp: Int!
  updatedTimestamp: Int
}

type Post @model {
  id: ID!
  user: User! @connection(name: "UserPosts")
  text: String
  imageUrl: String
  createdTimestamp: Int!
  updatedTimestamp: Int
}

Amplify will generate the following:

Post.swift

// swiftlint:disable all
import Amplify
import Foundation

public struct Post: Model {
  public let id: String
  public var user: User
  public var text: String?
  public var imageUrl: String?
  public var createdTimestamp: Int
  public var updatedTimestamp: Int?
  
  public init(id: String = UUID().uuidString,
      user: User,
      text: String? = nil,
      imageUrl: String? = nil,
      createdTimestamp: Int,
      updatedTimestamp: Int? = nil) {
      self.id = id
      self.user = user
      self.text = text
      self.imageUrl = imageUrl
      self.createdTimestamp = createdTimestamp
      self.updatedTimestamp = updatedTimestamp
  }
}

Post+schema.swift

// swiftlint:disable all
import Amplify
import Foundation

extension Post {
  // MARK: - CodingKeys 
   public enum CodingKeys: String, ModelKey {
    case id
    case user
    case text
    case imageUrl
    case createdTimestamp
    case updatedTimestamp
  }
  
  public static let keys = CodingKeys.self
  //  MARK: - ModelSchema 
  
  public static let schema = defineSchema { model in
    let post = Post.keys
    
    model.pluralName = "Posts"
    
    model.fields(
      .id(),
      .belongsTo(post.user, is: .required, ofType: User.self, targetName: "postUserId"),
      .field(post.text, is: .optional, ofType: .string),
      .field(post.imageUrl, is: .optional, ofType: .string),
      .field(post.createdTimestamp, is: .required, ofType: .int),
      .field(post.updatedTimestamp, is: .optional, ofType: .int)
    )
    }
}

as you can see post.user should have a target of postUserId however when using post.keys.user, the column cannot be found.

Solution:

To solve this issue, the following statement works:

Amplify.DataStore.query(Post.self, where: field("postUserId") == Service.shared.userId()

This does work, but without looking at the Post+schema, a user should not reasonably expect understand this, they should be able to look at the model to understand the connections, as the schema is really implementation details?

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingclosing soonThis issue will be closed in 7 days unless further comments are made.datastoreIssues related to the DataStore categorywork in progressIssues was triaged and investigation done

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions