in common/elasticsearch/esql/select.go [341:442]
func (e *ESql) convertComparisionExpr(expr sqlparser.Expr, parent sqlparser.Expr, not bool) (string, error) {
// extract lhs, and check lhs is a colName
var err error
scriptQuery := false
comparisonExpr := expr.(*sqlparser.ComparisonExpr)
lhsExpr, rhsExpr := comparisonExpr.Left, comparisonExpr.Right
var lhsStr, rhsStr, dsl string
// get operator
op := comparisonExpr.Operator
if not {
if _, exist := oppositeOperator[op]; !exist {
err := fmt.Errorf(`esql: %s operator not supported in comparison clause`, comparisonExpr.Operator)
return "", err
}
op = oppositeOperator[op]
}
if _, ok := lhsExpr.(*sqlparser.ColName); !ok {
scriptQuery = true
}
switch rhsExpr.(type) {
case *sqlparser.SQLVal, sqlparser.ValTuple:
rhsStr, err = e.convertValExpr(rhsExpr, false)
if err != nil {
return "", err
}
rhsStr, err = e.valueProcess(lhsStr, rhsStr)
if err != nil {
return "", err
}
default:
scriptQuery = true
}
// use painless scripting query here
if scriptQuery {
lhsStr, err = e.convertToScript(lhsExpr)
if err != nil {
return "", err
}
rhsStr, err = e.convertToScript(rhsExpr)
if err != nil {
return "", err
}
op, ok := op2PainlessOp[op]
if !ok {
err = fmt.Errorf("esql: not supported painless operator")
return "", err
}
script := fmt.Sprintf(`%v %v %v`, lhsStr, op, rhsStr)
dsl = fmt.Sprintf(`{"bool": {"filter": {"script": {"script": {"source": "%v"}}}}}`, script)
return dsl, nil
}
lhs := lhsExpr.(*sqlparser.ColName)
lhsStr, err = e.convertColName(lhs)
if err != nil {
return "", err
}
// generate dsl according to operator
switch op {
case "=":
dsl = fmt.Sprintf(`{"term": {"%v": "%v"}}`, lhsStr, rhsStr)
case "<":
dsl = fmt.Sprintf(`{"range": {"%v": {"lt": "%v"}}}`, lhsStr, rhsStr)
case "<=":
dsl = fmt.Sprintf(`{"range": {"%v": {"lte": "%v"}}}`, lhsStr, rhsStr)
case ">":
dsl = fmt.Sprintf(`{"range": {"%v": {"gt": "%v"}}}`, lhsStr, rhsStr)
case ">=":
dsl = fmt.Sprintf(`{"range": {"%v": {"gte": "%v"}}}`, lhsStr, rhsStr)
case "<>", "!=":
dsl = fmt.Sprintf(`{"bool": {"must_not": {"term": {"%v": "%v"}}}}`, lhsStr, rhsStr)
case "in":
rhsStr = strings.Replace(rhsStr, `'`, `"`, -1)
rhsStr = strings.Trim(rhsStr, "(")
rhsStr = strings.Trim(rhsStr, ")")
dsl = fmt.Sprintf(`{"terms": {"%v": [%v]}}`, lhsStr, rhsStr)
case "not in":
rhsStr = strings.Replace(rhsStr, `'`, `"`, -1)
rhsStr = strings.Trim(rhsStr, "(")
rhsStr = strings.Trim(rhsStr, ")")
dsl = fmt.Sprintf(`{"bool": {"must_not": {"terms": {"%v": [%v]}}}}`, lhsStr, rhsStr)
case "like":
rhsStr = strings.Replace(rhsStr, `_`, `?`, -1)
rhsStr = strings.Replace(rhsStr, `%`, `*`, -1)
dsl = fmt.Sprintf(`{"wildcard": {"%v": {"wildcard": "%v"}}}`, lhsStr, rhsStr)
case "not like":
rhsStr = strings.Replace(rhsStr, `_`, `?`, -1)
rhsStr = strings.Replace(rhsStr, `%`, `*`, -1)
dsl = fmt.Sprintf(`{"bool": {"must_not": {"wildcard": {"%v": {"wildcard": "%v"}}}}}`, lhsStr, rhsStr)
case "regexp":
dsl = fmt.Sprintf(`{"regexp": {"%v": "%v"}}`, lhsStr, rhsStr)
case "not regexp":
dsl = fmt.Sprintf(`{"bool": {"must_not": {"regexp": {"%v": "%v"}}}}`, lhsStr, rhsStr)
default:
err := fmt.Errorf(`esql: %s operator not supported in comparison clause`, comparisonExpr.Operator)
return "", err
}
return dsl, nil
}