Builds SQL for IN condition

@param string $operator
@param array|\Traversable $columns
@param array $values
@param array $params
@return string SQL
554680
protected function buildCompositeInCondition($operator, $columns, $values, &$params)
    {
        $vss = [];

        foreach ($values as $value) {
            $vs = [];

            foreach ($columns as $column) {
                if (isset($value[$column])) {
                    $phName = self::PARAM_PREFIX . count($params);
                    $params[$phName] = $value[$column];
                    $vs[] = $phName;
                }
                else {
                    $vs[] = 'NULL';
                }
            }

            $vss[] = '(' . implode(', ', $vs) . ')';
        }

        if (empty($vss)) {
            return $operator === 'IN' ? '0=1' : '';
        }

        $sqlColumns = [];

        foreach ($columns as $i => $column) {
            $sqlColumns[] = strpos($column, '(') === false ? $this->db->quoteColumnName($column) : $column;
        }

        return '(' . implode(', ', $sqlColumns) . ") $operator (" . implode(', ', $vss) . ')';
    }
1197241
public function orWhereRaw($column, $operator = null, ?string $raw = null)
	{
		return $this->whereRaw($column, $operator, $raw, 'OR');
	}
404823
public function where($column, $operator = null, $value = null, $boolean = 'and')
	{
        // First we check whether the operator is 'IN' so that we call whereIn() on it
        // as a helping hand and centralization strategy, whereIn knows what to do with the IN operator.
        if (mb_strtolower($operator) == 'in')
        {
            return $this->whereIn($column, $value, $boolean);
        }

        // If the column is an array, we will assume it is an array of key-value pairs
		// and can add them each as a where clause. We will maintain the boolean we
		// received when the method was called and pass it into the nested where.
		if (is_array($column))
		{
			return $this->whereNested(function(IlluminateQueryBuilder $query) use ($column)
			{
				foreach ($column as $key => $value)
				{
					$query->where($key, '=', $value);
				}
			}, $boolean);
		}

		if (func_num_args() == 2)
		{
			list($value, $operator) = array($operator, '=');
		}
		elseif ($this->invalidOperatorAndValue($operator, $value))
		{
			throw new \InvalidArgumentException("Value must be provided.");
		}

		// If the columns is actually a Closure instance, we will assume the developer
		// wants to begin a nested where statement which is wrapped in parenthesis.
		// We'll add that Closure to the query then return back out immediately.
		if ($column instanceof Closure)
		{
			return $this->whereNested($column, $boolean);
		}

		// If the given operator is not found in the list of valid operators we will
		// assume that the developer is just short-cutting the '=' operators and
		// we will set the operators to '=' and set the values appropriately.
		if ( ! in_array(mb_strtolower($operator), $this->operators, true))
		{
			list($value, $operator) = array($operator, '=');
		}

		// If the value is a Closure, it means the developer is performing an entire
		// sub-select within the query and we will need to compile the sub-select
		// within the where clause to get the appropriate query record results.
		if ($value instanceof Closure)
		{
			return $this->whereSub($column, $operator, $value, $boolean);
		}

		// If the value is "null", we will just assume the developer wants to add a
		// where null clause to the query. So, we will allow a short-cut here to
		// that method for convenience so the developer doesn't have to check.
		if (is_null($value))
		{
			return $this->whereNull($column, $boolean, $operator != '=');
		}

		// Now that we are working with just a simple query we can put the elements
		// in our array and add the query binding to our array of bindings that
		// will be bound to each SQL statements when it is finally executed.
		$type = 'Basic';

        $property = $column;

        // When the column is an id we need to treat it as a graph db id and transform it
        // into the form of id(n) and the typecast the value into int.
        if ($column == 'id')
        {
            $column = 'id('. $this->modelAsNode() .')';
            $value = intval($value);
        }
        // When it's been already passed in the form of NodeLabel.id we'll have to
        // re-format it into id(NodeLabel)
        elseif (preg_match('/^.*\.id$/', $column))
        {
            $parts = explode('.', $column);
            $column = sprintf('%s(%s)', $parts[1], $parts[0]);
            $value = intval($value);
        }
        // Also if the $column is already a form of id(n) we'd have to type-cast the value into int.
        elseif (preg_match('/^id\(.*\)$/', $column)) $value = intval($value);

        $binding = $this->prepareBindingColumn($column);

        $this->wheres[] = compact('type', 'binding', 'column', 'operator', 'value', 'boolean');

        $property = $this->wrap($binding);

        if ( ! $value instanceof Expression)
        {
			$this->addBinding([$property => $value], 'where');
		}

		return $this;
	}
380358
public function where($column, $operator = null, $value = null)
    {
        if ($column instanceof Closure) {
            return $this->whereNested('and', $column);
        }

        $constraint = call_user_func_array(
            [Constraint::class, 'where'],
            func_get_args()
        );

        return $this->addConstraint($constraint);
    }
464089
public function where($column, $operator, $value = null)
    {
        $instance = $this->whereStrategyInstance();

        $instance->whereStrategy()->where(...func_get_args());

        return $instance;
    }
299356
public function having($column, $operator = null, $value = null, $boolean = 'and')
    {
        $type = 'Basic';

        // Here we will make some assumptions about the operator. If only 2 values are
        // passed to the method, we will assume that the operator is an equals sign
        // and keep going. Otherwise, we'll require the operator to be passed in.
        [$value, $operator] = $this->prepareValueAndOperator(
            $value, $operator, func_num_args() === 2
        );

        // If the given operator is not found in the list of valid operators we will
        // assume that the developer is just short-cutting the '=' operators and
        // we will set the operators to '=' and set the values appropriately.
        if ($this->invalidOperator($operator)) {
            [$value, $operator] = [$operator, '='];
        }

        $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean');

        if (! $value instanceof Expression) {
            $this->addBinding($value, 'having');
        }

        return $this;
    }
441494
public function where(
        $column,
        $operator = null,
        $value = null,
        $boolean = 'and'
    ) {
        if (is_array($column)) {
            $this->_where = $column;
        }

        return $this;
    }
370884
public function generateWhere($conditions, &$where, &$values, &$types)
    {
        $where = "";

        // When empty where, no conditions, return and set where empty.
        if (count($conditions) == 0) {
            return;
        }

        $idx = 0;
        $max = count($conditions);

        foreach ($conditions as $criteria) {
            $column = $criteria['column'];
            $operator = $criteria['operator'];
            $value = $criteria['value'];

            // Prepare where clause
            $where .= "$column ";

            // Check our operator
            if ($operator === "IN") {
                // Prepare and loop
                $where .= "IN (";

                $subIdx = 0;
                $subMax = count($value);
                foreach ($value as $subValue) {

                    $where .= "?";
                    $values[] = $this->prepareData($subValue);
                    $types[] = $this->determinateType($subValue);

                    if (($subIdx+1) < $subMax) {
                        $where .= ",";
                    }
                    $subIdx++;
                }
                $where .= ")";
            } else {
                // Will add a normal operator
                $where .= "$operator ";

                $where .= "?";
                $values[] = $this->prepareData($value);
                $types[] = $this->determinateType($value);
            }

            // Adding AND if not last
            if (($idx + 1) < $max) {
                $where .= " AND ";
            }
            $idx++;
        }
    }
1085070
public function where($column, $operator, $value = null)
    {
        $this->wConditions()->column(...func_get_args());

        return $this;
    }
1274644
public function conditionFactory($column, $value, $operator = '=')
    {
        $currentOrIndex = isset($this->sql['where']['$or']) ? count($this->sql['where']['$or']) - 1 : 0;

        if ($this->opIsAnd) {
            if (isset($this->sql['where'][$column][$operator])) {
                throw new \InvalidArgumentException('Mongodb Where Op key Is Exists[' . $column . $operator . ']');
            }
        } else if ($this->bracketsIsOpen) {
            if (isset($this->sql['where']['$or'][$currentOrIndex][$column][$operator])) {
                throw new \InvalidArgumentException('Mongodb Where Op key Is Exists[' . $column . $operator . ']');
            }
        }

        switch ($operator) {
            case 'IN':
                // no break
            case 'NOT IN':
                empty($value) && $value = [0];
                //这边可直接跳过不组装sql，但是为了给用户提示无条件 便于调试还是加上where field in(0)
                if ($this->opIsAnd) {
                    $this->sql['where'][$column][$operator == 'IN' ? '$in' : '$nin'] = $value;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column][$operator == 'IN' ? '$in' : '$nin'] = $value;
                } else {
                    $this->sql['where']['$or'][][$column] = $operator == 'IN' ? ['$in' => $value] : ['$nin' => $value];
                }
                break;
            case 'BETWEEN':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$gt'] = $value[0];
                    $this->sql['where'][$column]['$lt'] = $value[1];
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$gt'] = $value[0];
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$lt'] = $value[1];
                } else {
                    $this->sql['where']['$or'][][$column] = ['$gt' => $value[0], '$lt' => $value[1]];
                }
                break;
            case 'NOT BETWEEN':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$lt'] = $value[0];
                    $this->sql['where'][$column]['$gt'] = $value[1];
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$lt'] = $value[0];
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$gt'] = $value[1];
                } else {
                    $this->sql['where']['$or'][][$column] = ['$lt' => $value[0], '$gt' => $value[1]];
                }
                break;
            case 'IS NULL':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$in'] = [null];
                    $this->sql['where'][$column]['$exists'] = true;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$in'] = [null];
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$exists'] = true;
                } else {
                    $this->sql['where']['$or'][][$column] = ['$in' => [null], '$exists' => true];
                }
                break;
            case 'IS NOT NULL':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$ne'] = null;
                    $this->sql['where'][$column]['$exists'] = true;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$ne'] = null;
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$exists'] = true;
                } else {
                    $this->sql['where']['$or'][][$column] = ['$ne' => null, '$exists' => true];
                }
                break;
            case '>':
                //no break;
            case '<':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column][$operator == '>' ? '$gt' : '$lt'] = $value;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column][$operator == '>' ? '$gt' : '$lt'] = $value;
                } else {
                    $this->sql['where']['$or'][][$column] = $operator == '>' ? ['$gt' => $value] : ['$lt' => $value];
                }
                break;
            case '>=':
                //no break;
            case '<=':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column][$operator == '>=' ? '$gte' : '$lte'] = $value;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column][$operator == '>=' ? '$gte' : '$lte'] = $value;
                } else {
                    $this->sql['where']['$or'][][$column] = $operator == '>=' ? ['$gte' => $value] : ['$lte' => $value];
                }
                break;
            case 'NOT LIKE':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$not'] = new Regex($value, 'i');
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$not'] = new Regex($value, 'i');
                } else {
                    $this->sql['where']['$or'][][$column] = ['$not' => new Regex($value, 'i')];
                }
                break;
            case 'LIKE':
                //no break;
            case 'REGEXP':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$regex'] = $value;
                    $this->sql['where'][$column]['$options'] = '$i';
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$regex'] = $value;
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$options'] = '$i';
                } else {
                    $this->sql['where']['$or'][][$column] = ['$regex' => $value, '$options' => '$i'];
                }
                break;
            case '!=':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column]['$ne'] = $value;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column]['$ne'] = $value;
                } else {
                    $this->sql['where']['$or'][][$column] = ['$ne' => $value];
                }
                break;
            case '=':
                if ($this->opIsAnd) {
                    $this->sql['where'][$column] = $value;
                } else if ($this->bracketsIsOpen) {
                    $this->sql['where']['$or'][$currentOrIndex][$column] = $value;
                } else {
                    $this->sql['where']['$or'][][$column] = $value;
                }
                break;
            case 'column':
                $this->sql['where']['$where'] = "this.{$column} = this.{$value}";
                break;
            case 'raw':
                $this->sql['where']['$where'] = $column;
                break;
        }
        return $this;
    }
1298170
private function buildHalfBoundedRangeCondition($operator, $operands)
    {
        if (!isset($operands[0], $operands[1])) {
            throw new InvalidParamException("Operator '$operator' requires two operands.");
        }

        list($column, $value) = $operands;
        if ($column == '_id') {
            $column = '_uid';
        }

        $range_operator = null;

        if (in_array($operator, ['gte', '>='])) {
            $range_operator = 'gte';
        } elseif (in_array($operator, ['lte', '<='])) {
            $range_operator = 'lte';
        } elseif (in_array($operator, ['gt', '>'])) {
            $range_operator = 'gt';
        } elseif (in_array($operator, ['lt', '<'])) {
            $range_operator = 'lt';
        }

        if ($range_operator === null) {
            throw new InvalidParamException("Operator '$operator' is not implemented.");
        }

        $filter = [
            'range' => [
                $column => [
                    $range_operator => $value
                ]
            ]
        ];

        return $filter;
    }
77434
public function where(string $column, $operator = null, $value = null): BaseQueryRelateContract
    {
        $this->query->where($column, $operator, $value);

        return $this;
    }
1311740
public function where($column, $operator = '=', $value = null, $boolean = 'and', array $columns = ['*'])
    {
        return $this->mediator->transform($this->mediator(func_get_args()));
    }
24874
public function setColumn($column, $operator = Condition::OPERATOR_OR)
    {
        $columnAlreadySet = count($this->column) > 0;
        if (!Condition::isOperator($operator) && $columnAlreadySet) {
            $msg = sprintf("Operator must be '%s' or '%s'.", Condition::OPERATOR_AND, Condition::OPERATOR_OR);
            throw new Exception($msg);
        }

        if ($columnAlreadySet) {
            $this->column[] = $operator;
            $this->column[] = $column;
        } else {
            $this->column[] = $column;
        }

        return $this;
    }
660719
public function where($column, $operator, $value = null)
    {
        if (is_null($value)) {
            if (is_callable($operator)) {
                $this->where[] = [$column, 'func', $operator];
            } else {
                $this->where[] = [$column, '=', $operator];
            }
        } else {
            $this->where[] = [$column, $operator, $value];
        }

        return $this;
    }
514831
public function where($column, $operator, $value, $quoted = false)
    {
        $this->where[] = array(
            'column' => $column,
            'operator' => $operator,
            'value' => $value,
            'quoted' => $quoted
        );
        return $this;
    }
830785
public function orWhere($column, $operator = null, $value = null)
    {
        [$value, $operator] = $this->prepareValueAndOperator(
            $value, $operator, func_num_args() === 2
        );

        return $this->where($column, $operator, $value, 'or');
    }