func buildSql()

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
}