in cassandra-bigtable-migration-tools/cassandra-bigtable-proxy/translator/utils.go [1103:1304]
func parseWhereByClause(input cql.IWhereSpecContext, tableName string, schemaMapping *schemaMapping.SchemaMappingConfig, keyspace string) (*QueryClauses, error) {
if input == nil {
return nil, errors.New("no input parameters found for clauses")
}
elements := input.RelationElements().AllRelationElement()
if elements == nil {
return nil, errors.New("no input parameters found for clauses")
}
if len(elements) == 0 {
return &QueryClauses{}, nil
}
var clauses []Clause
var response QueryClauses
var paramKeys []string
params := make(map[string]interface{})
for i, val := range elements {
if val == nil {
return nil, errors.New("could not parse column object")
}
s := strconv.Itoa(i + 1)
placeholder := "value" + s
operator := ""
paramKeys = append(paramKeys, placeholder)
colObj := val.OBJECT_NAME(0)
if colObj == nil {
return nil, errors.New("could not parse column object")
}
isInOperator := false
if val.OPERATOR_EQ() != nil {
operator = val.OPERATOR_EQ().GetText()
} else if val.OPERATOR_GT() != nil {
operator = val.OPERATOR_GT().GetSymbol().GetText()
} else if val.OPERATOR_LT() != nil {
operator = val.OPERATOR_LT().GetSymbol().GetText()
} else if val.OPERATOR_GTE() != nil {
operator = val.OPERATOR_GTE().GetSymbol().GetText()
} else if val.OPERATOR_LTE() != nil {
operator = val.OPERATOR_LTE().GetSymbol().GetText()
} else if val.KwIn() != nil {
operator = "IN"
isInOperator = true
} else {
return nil, errors.New("no supported operator found")
}
colName := colObj.GetText()
if colName == "" {
return nil, errors.New("could not parse column name")
}
colName = strings.ReplaceAll(colName, literalPlaceholder, "")
columnType, err := schemaMapping.GetColumnType(keyspace, tableName, colName)
if err != nil {
return nil, err
}
if columnType != nil && columnType.CQLType != "" {
if !isInOperator {
valConst := val.Constant()
if valConst == nil {
return nil, errors.New("could not parse value from query for one of the clauses")
}
value := val.Constant().GetText()
if value == "" {
return nil, errors.New("could not parse value from query for one of the clauses")
}
value = strings.ReplaceAll(value, "'", "")
if value != questionMark {
val, err := stringToPrimitives(value, columnType.CQLType)
if err != nil {
return nil, err
}
params[placeholder] = val
}
} else {
lower := strings.ToLower(val.GetText())
if !strings.Contains(lower, "?") {
valueFn := val.FunctionArgs()
if valueFn == nil {
return nil, errors.New("could not parse Function arguments")
}
value := valueFn.AllConstant()
if value == nil {
return nil, errors.New("could not parse all values inside IN operator")
}
switch columnType.CQLType {
case "int":
var allValues []int
for _, inVal := range value {
if inVal == nil {
return nil, errors.New("could not parse value")
}
valueTxt := inVal.GetText()
valueTxt = strings.ReplaceAll(valueTxt, "'", "")
i, err := strconv.Atoi(valueTxt)
if err != nil {
return nil, err
}
allValues = append(allValues, i)
}
params[placeholder] = allValues
case "bigint":
var allValues []int64
for _, inVal := range value {
if inVal == nil {
return nil, errors.New("could not parse value")
}
valueTxt := inVal.GetText()
valueTxt = strings.ReplaceAll(valueTxt, "'", "")
i, err := strconv.ParseInt(valueTxt, 10, 64)
if err != nil {
return nil, err
}
allValues = append(allValues, i)
}
params[placeholder] = allValues
case "float":
var allValues []float32
for _, inVal := range value {
if inVal == nil {
return nil, errors.New("could not parse value")
}
valueTxt := inVal.GetText()
valueTxt = strings.ReplaceAll(valueTxt, "'", "")
i, err := strconv.ParseFloat(valueTxt, 32)
if err != nil {
return nil, err
}
allValues = append(allValues, float32(i))
}
params[placeholder] = allValues
case "double":
var allValues []float64
for _, inVal := range value {
if inVal == nil {
return nil, errors.New("could not parse value")
}
valueTxt := inVal.GetText()
valueTxt = strings.ReplaceAll(valueTxt, "'", "")
i, err := strconv.ParseFloat(valueTxt, 64)
if err != nil {
return nil, err
}
allValues = append(allValues, i)
}
params[placeholder] = allValues
case "boolean":
var allValues []bool
for _, inVal := range value {
if inVal == nil {
return nil, errors.New("could not parse value")
}
valueTxt := inVal.GetText()
valueTxt = strings.ReplaceAll(valueTxt, "'", "")
val := (valueTxt == "true")
allValues = append(allValues, val)
}
params[placeholder] = allValues
case "blob":
case "varchar", "timestamp":
var allValues []string
for _, inVal := range value {
if inVal == nil {
return nil, errors.New("could not parse value")
}
valueTxt := inVal.GetText()
valueTxt = strings.ReplaceAll(valueTxt, "'", "")
allValues = append(allValues, valueTxt)
}
params[placeholder] = allValues
default:
err := errors.New("no correct Datatype found for column")
return nil, err
}
}
}
clause := &Clause{
Column: colName,
Operator: operator,
Value: "@" + placeholder,
IsPrimaryKey: columnType.IsPrimaryKey,
}
clauses = append(clauses, *clause)
}
}
response.Clauses = clauses
response.Params = params
response.ParamKeys = paramKeys
return &response, nil
}