func()

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
}