mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
revise FilterToSQLQuery function
This commit is contained in:
committed by
Dan Christian Bogos
parent
c9115da4b7
commit
082c412159
@@ -876,6 +876,11 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
var restOfItems string // Excluding ~*req, hold the rest of the items past the first one. If only 1 item in all element, holds that item. e.g. "Charges[0].RatingID" out of ~*req.cost_details.Charges[0].RatingID or "answer_time" out of ~*req.answer_time
|
||||
not := strings.HasPrefix(fltr.Type, utils.MetaNot)
|
||||
elementItems := fltr.ElementItems()[1:] // exclude first item: ~*req
|
||||
for i := range elementItems { // encapsulate with "" strings starting with *
|
||||
if strings.HasPrefix(elementItems[i], utils.Meta) {
|
||||
elementItems[i] = "\"" + elementItems[i] + "\""
|
||||
}
|
||||
}
|
||||
if len(elementItems) > 1 {
|
||||
firstItem = elementItems[0]
|
||||
restOfItems = strings.Join(elementItems[1:], utils.NestingSep)
|
||||
@@ -892,7 +897,11 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
conditions = append(conditions, fmt.Sprintf("%s IS NULL", restOfItems))
|
||||
return
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') IS NULL", firstItem, restOfItems))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') IS NULL", firstItem, restOfItems)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
return
|
||||
}
|
||||
// existing means Column IS NOT NULL
|
||||
@@ -900,21 +909,33 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
conditions = append(conditions, fmt.Sprintf("%s IS NOT NULL", restOfItems))
|
||||
return
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') IS NOT NULL", firstItem, restOfItems))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') IS NOT NULL", firstItem, restOfItems)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
case utils.MetaEmpty, utils.MetaNotEmpty:
|
||||
if not {
|
||||
if firstItem == utils.EmptyString {
|
||||
conditions = append(conditions, fmt.Sprintf("%s != ''", restOfItems))
|
||||
return
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') != ''", firstItem, restOfItems))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') != ''", firstItem, restOfItems)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
return
|
||||
}
|
||||
if firstItem == utils.EmptyString {
|
||||
conditions = append(conditions, fmt.Sprintf("%s == ''", restOfItems))
|
||||
return
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') == ''", firstItem, restOfItems))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') == ''", firstItem, restOfItems)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -934,14 +955,22 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
conditions = append(conditions, fmt.Sprintf("%s != '%s'", restOfItems, value))
|
||||
continue
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') != '%s'",
|
||||
firstItem, restOfItems, value))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') != '%s'",
|
||||
firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
continue
|
||||
}
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s = '%s'", restOfItems, value)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') = '%s'", firstItem, restOfItems, value)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') = '%s'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
case utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual:
|
||||
parsedValAny := utils.StringToInterface(value)
|
||||
@@ -950,25 +979,41 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s >= '%v'", restOfItems, parsedValAny)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') >= '%v'", firstItem, restOfItems, parsedValAny)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') >= '%v'", firstItem, restOfItems, parsedValAny)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
case utils.MetaGreaterThan:
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s > '%v'", restOfItems, parsedValAny)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') > '%v'", firstItem, restOfItems, parsedValAny)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') > '%v'", firstItem, restOfItems, parsedValAny)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
case utils.MetaLessOrEqual:
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s <= '%v'", restOfItems, parsedValAny)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') <= '%v'", firstItem, restOfItems, parsedValAny)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') <= '%v'", firstItem, restOfItems, parsedValAny)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
case utils.MetaLessThan:
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s < '%v'", restOfItems, parsedValAny)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') < '%v'", firstItem, restOfItems, parsedValAny)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') < '%v'", firstItem, restOfItems, parsedValAny)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
}
|
||||
case utils.MetaPrefix, utils.MetaNotPrefix:
|
||||
@@ -977,13 +1022,21 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
conditions = append(conditions, fmt.Sprintf("%s NOT LIKE '%s%%'", restOfItems, value))
|
||||
continue
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') NOT LIKE '%s%%'", firstItem, restOfItems, value))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') NOT LIKE '%s%%'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
continue
|
||||
}
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s LIKE '%s%%'", restOfItems, value)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') LIKE '%s%%'", firstItem, restOfItems, value)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') LIKE '%s%%'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
case utils.MetaSuffix, utils.MetaNotSuffix:
|
||||
if not {
|
||||
@@ -991,13 +1044,21 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
conditions = append(conditions, fmt.Sprintf("%s NOT LIKE '%%%s'", restOfItems, value))
|
||||
continue
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') NOT LIKE '%%%s'", firstItem, restOfItems, value))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') NOT LIKE '%%%s'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
continue
|
||||
}
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s LIKE '%%%s'", restOfItems, value)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') LIKE '%%%s'", firstItem, restOfItems, value)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') LIKE '%%%s'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
case utils.MetaRegex, utils.MetaNotRegex:
|
||||
if not {
|
||||
@@ -1005,13 +1066,21 @@ func (fltr *FilterRule) FilterToSQLQuery() (conditions []string) {
|
||||
conditions = append(conditions, fmt.Sprintf("%s NOT REGEXP '%s'", restOfItems, value))
|
||||
continue
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("JSON_VALUE(%s, '$.%s') NOT REGEXP '%s'", firstItem, restOfItems, value))
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') NOT REGEXP '%s'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
conditions = append(conditions, queryPart)
|
||||
continue
|
||||
}
|
||||
if firstItem == utils.EmptyString {
|
||||
singleCond = fmt.Sprintf("%s REGEXP '%s'", restOfItems, value)
|
||||
} else {
|
||||
singleCond = fmt.Sprintf("JSON_VALUE(%s, '$.%s') REGEXP '%s'", firstItem, restOfItems, value)
|
||||
queryPart := fmt.Sprintf("JSON_VALUE(%s, '$.%s') REGEXP '%s'", firstItem, restOfItems, value)
|
||||
if strings.HasPrefix(restOfItems, `"*`) {
|
||||
queryPart = fmt.Sprintf("JSON_UNQUOTE(%s)", queryPart)
|
||||
}
|
||||
singleCond = queryPart
|
||||
}
|
||||
}
|
||||
conditions = append(conditions, singleCond)
|
||||
|
||||
@@ -3324,6 +3324,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.name') LIKE 'prefix%'"},
|
||||
},
|
||||
{
|
||||
name: "Prefix LIKE with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaPrefix,
|
||||
Element: "~*req.data.*name",
|
||||
Values: []string{"prefix"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*name"') LIKE 'prefix%')`},
|
||||
},
|
||||
{
|
||||
name: "Suffix NOT LIKE with empty beforeSep",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3342,6 +3351,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.name') LIKE '%suffix'"},
|
||||
},
|
||||
{
|
||||
name: "Suffix LIKE with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaSuffix,
|
||||
Element: "~*req.data.*name",
|
||||
Values: []string{"suffix"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*name"') LIKE '%suffix')`},
|
||||
},
|
||||
{
|
||||
name: "Regex NOT REGEXP with empty beforeSep",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3360,7 +3378,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.pattern') REGEXP '[0-9]+'"},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Regex REGEXP with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaRegex,
|
||||
Element: "~*req.data.*pattern",
|
||||
Values: []string{"[0-9]+"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*pattern"') REGEXP '[0-9]+')`},
|
||||
},
|
||||
{
|
||||
name: "Not equal with empty beforeSep",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3379,6 +3405,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.status') = 'active'"},
|
||||
},
|
||||
{
|
||||
name: "Equal condition with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaString,
|
||||
Element: "~*req.data.*status",
|
||||
Values: []string{"active"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*status"') = 'active')`},
|
||||
},
|
||||
{
|
||||
name: "Greater than condition with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3388,6 +3423,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.score') > '50'"},
|
||||
},
|
||||
{
|
||||
name: "Greater than condition with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaGreaterThan,
|
||||
Element: "~*req.data.*score",
|
||||
Values: []string{"50"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*score"') > '50')`},
|
||||
},
|
||||
{
|
||||
name: "Less than or equal condition with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3397,6 +3441,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.score') <= '30'"},
|
||||
},
|
||||
{
|
||||
name: "Less than or equal condition with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaLessOrEqual,
|
||||
Element: "~*req.data.*score",
|
||||
Values: []string{"30"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*score"') <= '30')`},
|
||||
},
|
||||
{
|
||||
name: "Less than condition with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3406,7 +3459,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(data, '$.score') < '20'"},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Less than condition with * column with JSON_VALUE",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaLessThan,
|
||||
Element: "~*req.data.*score",
|
||||
Values: []string{"20"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(data, '$."*score"') < '20')`},
|
||||
},
|
||||
{
|
||||
name: "MetaExists with no values",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3425,6 +3486,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(json_field, '$.key') IS NULL"},
|
||||
},
|
||||
{
|
||||
name: "MetaNotExists with *column with no values",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaNotExists,
|
||||
Element: "~*req.json_field.*key",
|
||||
Values: nil,
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(json_field, '$."*key"') IS NULL)`},
|
||||
},
|
||||
{
|
||||
name: "MetaString with values",
|
||||
fltrRule: FilterRule{
|
||||
@@ -3443,6 +3513,15 @@ func TestFilterToSQLQueryValidations(t *testing.T) {
|
||||
},
|
||||
expected: []string{"JSON_VALUE(json_field, '$.key') NOT LIKE 'prefix1%'"},
|
||||
},
|
||||
{
|
||||
name: "MetaPrefix with *column name NOT condition",
|
||||
fltrRule: FilterRule{
|
||||
Type: utils.MetaNotPrefix,
|
||||
Element: "~*req.json_field.*key",
|
||||
Values: []string{"prefix1"},
|
||||
},
|
||||
expected: []string{`JSON_UNQUOTE(JSON_VALUE(json_field, '$."*key"') NOT LIKE 'prefix1%')`},
|
||||
},
|
||||
{
|
||||
name: "MetaRegex with multiple values",
|
||||
fltrRule: FilterRule{
|
||||
|
||||
Reference in New Issue
Block a user