mirror of https://github.com/usememos/memos.git
fix(tags): ensure JSON array elements are properly formatted in SQL queries
This commit is contained in:
parent
671f4bf88b
commit
2385f48e4c
|
|
@ -266,7 +266,7 @@ func (c *CommonSQLConverter) handleTagInList(ctx *ConvertContext, values []any)
|
||||||
template := c.dialect.GetJSONContains("$.tags", "element")
|
template := c.dialect.GetJSONContains("$.tags", "element")
|
||||||
sql := strings.Replace(template, "?", c.dialect.GetParameterPlaceholder(c.paramIndex), 1)
|
sql := strings.Replace(template, "?", c.dialect.GetParameterPlaceholder(c.paramIndex), 1)
|
||||||
subconditions = append(subconditions, sql)
|
subconditions = append(subconditions, sql)
|
||||||
args = append(args, v)
|
args = append(args, fmt.Sprintf(`"%s"`, v))
|
||||||
}
|
}
|
||||||
c.paramIndex++
|
c.paramIndex++
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -185,12 +185,12 @@ func (d *PostgreSQLDialect) GetJSONArrayLength(path string) string {
|
||||||
|
|
||||||
func (d *PostgreSQLDialect) GetJSONContains(path, _ string) string {
|
func (d *PostgreSQLDialect) GetJSONContains(path, _ string) string {
|
||||||
jsonPath := strings.Replace(path, "$.tags", "payload->'tags'", 1)
|
jsonPath := strings.Replace(path, "$.tags", "payload->'tags'", 1)
|
||||||
return fmt.Sprintf("%s.%s @> jsonb_build_array(?)", d.GetTablePrefix(), jsonPath)
|
return fmt.Sprintf("%s.%s @> jsonb_build_array(?::json)", d.GetTablePrefix(), jsonPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PostgreSQLDialect) GetJSONLike(path, _ string) string {
|
func (d *PostgreSQLDialect) GetJSONLike(path, _ string) string {
|
||||||
jsonPath := strings.Replace(path, "$.tags", "payload->'tags'", 1)
|
jsonPath := strings.Replace(path, "$.tags", "payload->'tags'", 1)
|
||||||
return fmt.Sprintf("%s.%s @> jsonb_build_array(?)", d.GetTablePrefix(), jsonPath)
|
return fmt.Sprintf("%s.%s @> jsonb_build_array(?::json)", d.GetTablePrefix(), jsonPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*PostgreSQLDialect) GetBooleanValue(value bool) interface{} {
|
func (*PostgreSQLDialect) GetBooleanValue(value bool) interface{} {
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ func TestConvertExprToSQL(t *testing.T) {
|
||||||
{
|
{
|
||||||
filter: `tag in ["tag1", "tag2"]`,
|
filter: `tag in ["tag1", "tag2"]`,
|
||||||
want: "(JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?) OR JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?))",
|
want: "(JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?) OR JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?))",
|
||||||
args: []any{"tag1", "tag2"},
|
args: []any{`"tag1"`, `"tag2"`},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `!(tag in ["tag1", "tag2"])`,
|
filter: `!(tag in ["tag1", "tag2"])`,
|
||||||
want: "NOT ((JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?) OR JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?)))",
|
want: "NOT ((JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?) OR JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?)))",
|
||||||
args: []any{"tag1", "tag2"},
|
args: []any{`"tag1"`, `"tag2"`},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `content.contains("memos")`,
|
filter: `content.contains("memos")`,
|
||||||
|
|
@ -43,7 +43,7 @@ func TestConvertExprToSQL(t *testing.T) {
|
||||||
{
|
{
|
||||||
filter: `tag in ['tag1'] || content.contains('hello')`,
|
filter: `tag in ['tag1'] || content.contains('hello')`,
|
||||||
want: "(JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?) OR `memo`.`content` LIKE ?)",
|
want: "(JSON_CONTAINS(JSON_EXTRACT(`memo`.`payload`, '$.tags'), ?) OR `memo`.`content` LIKE ?)",
|
||||||
args: []any{"tag1", "%hello%"},
|
args: []any{`"tag1"`, "%hello%"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `1`,
|
filter: `1`,
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ func TestConvertExprToSQL(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
filter: `tag in ["tag1", "tag2"]`,
|
filter: `tag in ["tag1", "tag2"]`,
|
||||||
want: "(memo.payload->'tags' @> jsonb_build_array($1) OR memo.payload->'tags' @> jsonb_build_array($2))",
|
want: "(memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags' @> jsonb_build_array($2::json))",
|
||||||
args: []any{"tag1", "tag2"},
|
args: []any{`"tag1"`, `"tag2"`},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `!(tag in ["tag1", "tag2"])`,
|
filter: `!(tag in ["tag1", "tag2"])`,
|
||||||
want: "NOT ((memo.payload->'tags' @> jsonb_build_array($1) OR memo.payload->'tags' @> jsonb_build_array($2)))",
|
want: "NOT ((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags' @> jsonb_build_array($2::json)))",
|
||||||
args: []any{"tag1", "tag2"},
|
args: []any{`"tag1"`, `"tag2"`},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `content.contains("memos")`,
|
filter: `content.contains("memos")`,
|
||||||
|
|
@ -42,8 +42,8 @@ func TestConvertExprToSQL(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `tag in ['tag1'] || content.contains('hello')`,
|
filter: `tag in ['tag1'] || content.contains('hello')`,
|
||||||
want: "(memo.payload->'tags' @> jsonb_build_array($1) OR memo.content ILIKE $2)",
|
want: "(memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.content ILIKE $2)",
|
||||||
args: []any{"tag1", "%hello%"},
|
args: []any{`"tag1"`, "%hello%"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `1`,
|
filter: `1`,
|
||||||
|
|
@ -107,7 +107,7 @@ func TestConvertExprToSQL(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: `"work" in tags`,
|
filter: `"work" in tags`,
|
||||||
want: "memo.payload->'tags' @> jsonb_build_array($1)",
|
want: "memo.payload->'tags' @> jsonb_build_array($1::json)",
|
||||||
args: []any{"work"},
|
args: []any{"work"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue