You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: sort_value.go
    path of file: ./repos/csvq/lib/query
    
    the code of the file until where you have to start completion: package query

import (
	"bytes"
	"math"
	"strings"

	"github.com/mithrandie/csvq/lib/option"
	"github.com/mithrandie/csvq/lib/parser"
	"github.com/mithrandie/csvq/lib/value"

	"github.com/mithrandie/ternary"
)

type SortValueType int

const (
	NullType SortValueType = iota
	IntegerType
	FloatType
	DatetimeType
	BooleanType
	StringType
)

type SortValues []*SortValue

func (values SortValues) Less(compareValues SortValues, directions []int, nullPositions []int) bool {
	for i, val := range values {
		t := val.Less(compareValues[i])
		if t != ternary.UNKNOWN {
			if directions[i] == parser.ASC {
				return t == ternary.TRUE
			} else {
				return t == ternary.FALSE
			}
		}

		if val.Type == NullType && compareValues[i].Type != NullType {
			if nullPositions[i] == parser.FIRST {
				return true
			} else {
				return false
    
func (v *SortValue) EquivalentTo(compareValue *SortValue) bool {
	if v.SerializedKey != nil {
		return bytes.Equal(v.SerializedKey.Bytes(), compareValue.SerializedKey.Bytes())
	}

	switch v.Type {
	case IntegerType:
		switch compareValue.Type {
		case IntegerType, BooleanType:
			return v.Integer == compareValue.Integer
		}
	case FloatType:
		switch compareValue.Type {
		case FloatType:
			if math.IsNaN(v.Float) && math.IsNaN(compareValue.Float) {
				return true
			}
			return v.Float == compareValue.Float
		}
	case DatetimeType:
		switch compareValue.Type {
		case DatetimeType:
			return v.Datetime == compareValue.Datetime
		}
	case BooleanType:
		switch compareValue.Type {
		case BooleanType, IntegerType:
			return v.Integer == compareValue.Integer
		}
	case StringType:
		switch compareValue.Type {
		case StringType:
			return v.String == compareValue.String
		}
	case NullType:
		return compareValue.Type == NullType
	}

	return false
}