in pkg/data-query/dataQuery.go [224:379]
func buildSql(query Query, table string) (string, map[string]int, error) {
var sb strings.Builder
sb.WriteString("select")
// the only array join is supported for now
arrayJoin := ""
for _, dimension := range query.Fields {
if dimension.arrayJoin != "" {
// the only array join is supported for now
arrayJoin = dimension.arrayJoin
// for field add distinct to filter duplicates out
// sb.WriteString(" distinct ")
break
}
}
columnNameToIndex := make(map[string]int, len(query.Dimensions)+len(query.Fields))
columnIndex := 0
dimensionWritten := false
for _, dimension := range query.Dimensions {
// check that the field with the same name doesn't exists
fieldExist := false
for _, field := range query.Fields {
if field.Name == dimension.Name {
fieldExist = true
break
}
}
if !fieldExist {
if !dimensionWritten {
sb.WriteRune(' ')
} else {
sb.WriteRune(',')
}
columnNameToIndex[dimension.Name] = columnIndex
columnIndex++
writeDimension(dimension, &sb)
dimensionWritten = true
}
}
// write extra fields to the end, so, it maybe skipped during serialization
for i, field := range query.Fields {
if i != 0 || dimensionWritten {
sb.WriteRune(',')
}
sb.WriteRune(' ')
if field.Sql != "" {
columnNameToIndex[field.Name] = columnIndex
columnIndex++
writeDimension(field, &sb)
continue
}
effectiveColumnName := ""
if query.Aggregator != "" {
sb.WriteString(query.Aggregator)
sb.WriteRune('(')
}
if field.metricPath == "" {
sb.WriteString(field.Name)
effectiveColumnName = field.Name
} else {
// select JSONExtractInt(arrayFirst(it -> JSONExtractString(it, 'n') = 'start main frontend', JSONExtractArrayRaw(raw_report, 'prepareAppInitActivities')), 'd') as v
// from report;
if field.metricValueName == 'e' {
// arraySum(it -> it.1 = 's' or it.1 = 'd' ? it.2 : 0, JSONExtractKeysAndValues(arrayFirst(it -> JSONExtractString(it, 'n') = 'render', JSONExtractArrayRaw(raw_report, 'prepareAppInitActivities')), 'Int'))
sb.WriteString("arraySum(it -> it.1 = 's' or it.1 = 'd' ? it.2 : 0, JSONExtractKeysAndValues(")
writeExtractJsonObject(&sb, field)
sb.WriteString(", 'Int'))")
} else {
sb.WriteString("JSONExtractInt(")
writeExtractJsonObject(&sb, field)
sb.WriteString(", '")
sb.WriteRune(field.metricValueName)
sb.WriteString("')")
}
}
if query.Aggregator != "" {
sb.WriteRune(')')
}
if field.resultPropertyName != "" {
sb.WriteString(" as ")
sb.WriteString(field.resultPropertyName)
effectiveColumnName = field.resultPropertyName
} else if query.Aggregator != "" {
sb.WriteString(" as ")
if field.arrayJoin == "" {
effectiveColumnName = field.Name
} else {
// measures.values is not a valid field name
effectiveColumnName = "measure_value"
}
sb.WriteString(effectiveColumnName)
}
columnNameToIndex[effectiveColumnName] = columnIndex
columnIndex++
}
sb.WriteString(" from ")
sb.WriteString(table)
if arrayJoin == "" {
for _, dimension := range query.Dimensions {
if dimension.arrayJoin != "" {
arrayJoin = dimension.arrayJoin
break
}
}
}
if arrayJoin != "" {
sb.WriteString(" array join ")
sb.WriteString(arrayJoin)
}
if len(query.Filters) != 0 {
err := writeWhereClause(&sb, query)
if err != nil {
return "", nil, err
}
}
if len(query.Dimensions) != 0 {
sb.WriteString(" group by")
for i, dimension := range query.Dimensions {
if i != 0 {
sb.WriteRune(',')
}
sb.WriteRune(' ')
sb.WriteString(dimension.Name)
}
}
if len(query.Order) != 0 {
sb.WriteString(" order by")
for i, field := range query.Order {
if i != 0 {
sb.WriteRune(',')
}
sb.WriteRune(' ')
sb.WriteString(field)
}
}
return sb.String(), columnNameToIndex, nil
}