loopbackio / loopbackio/loopback-connector-postgresql
eq object (JSON columns) doesn't work
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- JavaScript
- Star
- 118
- Fork
- 184
- Merge trung bình
- 1 ngày 22 giờ
- Pull request đã merge (30 ngày)
- 5
Mô tả
## Steps to reproduce
1. Create a model that has an object column, mapped as a JSON type in PostgreSQL
2. Try to do a `find` searching for a full value in that property/column, e.g. `const objectValue = {a: 1, b: 2};` and then `repo.find({where: {objectProperty: objectValue}})` or `repo.find({where: {objectProperty: {eq: objectValue}}})`
## Current Behavior
1. The `{objectProperty: {eq: value}}` is translated down into `{objectProperty: value}`
2. This line assumes that, if the value is an object, it must contain exactly one field that must be an operator: https://github.com/strongloop/loopback-connector-postgresql/blob/master/lib/postgresql.js#L654
3. It tries to map e.g. `a` as an operator name
4. The `buildExpression` operator switch hits its `default` clause which delegates to the base class in `loopback-connector`: https://github.com/strongloop/loopback-connector-postgresql/blob/master/lib/postgresql.js#L540-L543
5. That base class method has a `switch` with _no_ `default` clause, so it doesn't throw any errors and just concatenates the column name with the placeholder for the value: https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L969
6. And so it generates invalid SQL that looks like `"columName"$1`
## Expected Behavior
* I should be able to use object values in where clauses if the property contains object values
## Link to reproduction sandbox
WIP -- NB: encountering this in an LB4 app
## Additional information
* Running on `linux x64 12.22.1`
* `npm ls` doesn't work with `rush`, but using `loopback-connector-postgresql` v5.0.1, with `loopback-connector` v4.11.1, and the following LB4 components:
* `"@loopback/boot": "2.2.0"`
* `"@loopback/context": "3.9.3"`
* `"@loopback/core": "2.5.0"`
* `"@loopback/metadata": "2.2.6"`
* `"@loopback/openapi-v3": "3.3.1"`
* `"@loopback/openapi-v3-types": "1.2.1"`
* `"@loopback/repository": "2.4.0"`
* `"@loopback/rest": "4.0.0"`
* `"@loopback/rest-explorer": "2.2.0"`
## Related Issues
Haven't found any yet
## Workaround
Create a custom class to represent the value, and then have the equality comparison value use that, e.g. something like this, but without the prototype pollution vulnerabilities:
```typescript
class JSONWrapper {
[k: string]: any
constructor(value: any) {
Object.assign(this, value)
}
}
// elsewhere:
repo.find({where: {objectProperty: new JSONWrapper(objectValue)}});
```
This causes the `expression.constructor === Object` check to fail, and so it doesn't try to unwrap the value
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Start in lib/postgresql.js at the operator parsing and buildExpression locations cited in the report, then inspect the related base logic in loopback-connector/lib/sql.js. Reproduce the JSON-column equality query against PostgreSQL and trace how the object value becomes SQL. Done means object values in where clauses generate valid SQL and return matching records, with regression coverage in the relevant connector tests.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- javascript, postgresql
- Lĩnh vực
- databases
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 48/100