buildBaseSelect constructs a base SELECT node against the underlying table.
(alias string, comparison bool)
| 1048 | |
| 1049 | // buildBaseSelect constructs a base SELECT node against the underlying table. |
| 1050 | func (a *AST) buildBaseSelect(alias string, comparison bool) (*SelectNode, error) { |
| 1051 | n := &SelectNode{ |
| 1052 | Alias: alias, |
| 1053 | DimFields: a.dimFields, |
| 1054 | Unnests: a.unnests, |
| 1055 | Group: true, |
| 1056 | FromTable: a.underlyingTable, |
| 1057 | Where: a.underlyingWhere, |
| 1058 | } |
| 1059 | |
| 1060 | if a.Query.Rows { |
| 1061 | n.Group = false |
| 1062 | } |
| 1063 | |
| 1064 | tr := a.Query.TimeRange |
| 1065 | if comparison { |
| 1066 | n.DimFields = a.comparisonDimFields |
| 1067 | tr = a.Query.ComparisonTimeRange |
| 1068 | } |
| 1069 | |
| 1070 | err := a.AddTimeRange(n, tr) |
| 1071 | if err != nil { |
| 1072 | return nil, fmt.Errorf("failed to add time range: %w", err) |
| 1073 | } |
| 1074 | |
| 1075 | // If there is a spine, we wrap the base SELECT in a new SELECT that we add the spine to. |
| 1076 | // We do not join the spine directly to the FromTable because the join would be evaluated before the GROUP BY, |
| 1077 | // which would impact the measure aggregations (e.g. counts per group would be wrong). |
| 1078 | if a.Query.Spine != nil && !(a.Query.Spine.TimeRange != nil && comparison) { // Skip time range spines in the comparison select |
| 1079 | sn, err := a.buildSpineSelect(a.GenerateIdentifier(), a.Query.Spine, tr) |
| 1080 | if err != nil { |
| 1081 | return nil, err |
| 1082 | } |
| 1083 | |
| 1084 | a.WrapSelect(n, a.GenerateIdentifier()) |
| 1085 | n.SpineSelect = sn |
| 1086 | |
| 1087 | // Update the dimension fields to derive from the SpineSelect instead of the FromSelect |
| 1088 | // (since by definition, some dimension values in the spine might not be present in FromSelect). |
| 1089 | for i, f := range n.DimFields { |
| 1090 | f.Expr = a.Dialect.EscapeMemberAlias(sn.Alias, f.Name) |
| 1091 | n.DimFields[i] = f |
| 1092 | } |
| 1093 | } |
| 1094 | |
| 1095 | return n, nil |
| 1096 | } |
| 1097 | |
| 1098 | // buildSpineSelect constructs a SELECT node for the given spine of dimension values. |
| 1099 | func (a *AST) buildSpineSelect(alias string, spine *Spine, tr *TimeRange) (*SelectNode, error) { |
no test coverage detected