func()

in query/sql/sql_parser.go [405:518]


func (v *ASTBuilder) VisitQuerySpecification(ctx *antlrgen.QuerySpecificationContext) interface{} {
	v.Logger.Debugf("VisitQuerySpecification: %s", ctx.GetText())

	level, levelWith, levelQuery := v.getCtxLevels(v.SQL2AqlCtx)

	// handle from => join/table
	// first process from clause so that subquery/withQuery identifier can be found in expression
	v.SQL2AqlCtx.exprOrigin = ExprOriginJoinOn
	ctxArrRelation := ctx.AllRelation()
	arrRelations := make([]tree.IRelation, len(ctxArrRelation))
	for i, c := range ctxArrRelation {
		v.setCtxLevels(v.SQL2AqlCtx, level, levelWith, levelQuery)
		arrRelations[i], _ = v.Visit(c).(tree.IRelation)
	}

	var myFrom tree.IRelation
	if len(arrRelations) > 0 {
		relationL := arrRelations[0]
		// synthesize implicit join nodes
		for i := 1; i < len(arrRelations); i++ {
			relationR := arrRelations[i]
			relationL = tree.NewJoin(v.getLocation(ctx), tree.IMPLICIT, relationL, relationR, nil)
			relationL.SetValue(fmt.Sprintf("Join: (%s)", v.getText(ctxArrRelation[i])))
		}
		myFrom = relationL
	}

	// handle select => measure
	v.SQL2AqlCtx.exprOrigin = ExprOriginOthers
	ctxArrSelectItem := ctx.AllSelectItem()
	arrSelectItems := make([]tree.ISelectItem, len(ctxArrSelectItem))
	for i, c := range ctxArrSelectItem {
		v.setCtxLevels(v.SQL2AqlCtx, level, levelWith, levelQuery)
		arrSelectItems[i], _ = v.Visit(c).(tree.ISelectItem)

		if i < len(v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey]) {
			// handle subquery/withQuery with columnAliases,8
			// subquery/withQuery columnalias has higher priority, ignore subquery/withQuery selectSingle identifier
			switch item := arrSelectItems[i].(type) {
			case *tree.SingleColumn:
				v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey][i].Expr = util.GetSubstring(item.Expression.GetValue())
			case *tree.AllColumns:
				v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey][i].Expr = v.getText(c)
			}
		} else {
			// handle query or subquery/withQuery w/o columnAliases
			switch item := arrSelectItems[i].(type) {
			case *tree.SingleColumn:
				var alias string
				if item.Alias != nil {
					alias = util.GetSubstring(item.Alias.GetValue())
				}
				v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey] = append(v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey],
					queryCom.Measure{
						Alias: alias,
						Expr:  util.GetSubstring(item.Expression.GetValue()),
					})
			case *tree.AllColumns:
				v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey] = append(v.SQL2AqlCtx.MapMeasures[v.SQL2AqlCtx.mapKey],
					queryCom.Measure{
						Expr: v.getText(c),
					})
			}
		}
	}

	// handle where => rowfilter/timefilter
	v.setCtxLevels(v.SQL2AqlCtx, level, levelWith, levelQuery)
	v.SQL2AqlCtx.exprOrigin = ExprOriginWhere
	v.SQL2AqlCtx.exprCheck = true
	v.visitIfPresent(ctx.GetWhere(), reflect.TypeOf((*tree.Expression)(nil)))
	v.SQL2AqlCtx.exprCheck = false
	myWhere := v.visitIfPresent(ctx.GetWhere(), reflect.TypeOf((*tree.Expression)(nil))).(tree.IExpression)

	// handle group by => dimension
	if v.SQL2AqlCtx.disableMainGroupBy && levelQuery == 0 && ctx.GroupBy() != nil {
		// disable group by clause in manin query if with/subquery exists
		location := v.getLocation(ctx.GroupBy())
		panic(fmt.Errorf("group by is not allowed at (line:%d, col:%d) since with/subQuery already has group by",
			location.Line, location.CharPosition))
	}
	v.setCtxLevels(v.SQL2AqlCtx, level, levelWith, levelQuery)
	v.SQL2AqlCtx.exprOrigin = ExprOriginGroupBy
	myGroupBy := v.visitIfPresent(ctx.GroupBy(), reflect.TypeOf((*tree.GroupBy)(nil))).(*tree.GroupBy)
	if ctx.GroupBy() != nil && levelQuery > 0 {
		v.SQL2AqlCtx.disableMainGroupBy = true
	}

	// handle having => not support in AQL
	if ctx.GetHaving() != nil {
		location := v.getLocation(ctx.GetHaving())
		panic(fmt.Errorf("having not yet supported at (line:%d, col:%d)", location.Line, location.CharPosition))
	}
	v.setCtxLevels(v.SQL2AqlCtx, level, levelWith, levelQuery)
	v.SQL2AqlCtx.exprOrigin = ExprOriginOthers
	v.SQL2AqlCtx.exprCheck = true
	v.visitIfPresent(ctx.GetHaving(), reflect.TypeOf((*tree.Expression)(nil)))
	v.SQL2AqlCtx.exprCheck = false
	myHaving := v.visitIfPresent(ctx.GetHaving(), reflect.TypeOf((*tree.Expression)(nil))).(tree.IExpression)

	querySpec := tree.NewQuerySpecification(
		v.getLocation(ctx),
		tree.NewSelect(v.getLocation(ctx), v.isDistinct(ctx.SetQuantifier()), arrSelectItems),
		myFrom,
		myWhere,
		myGroupBy,
		myHaving,
		nil,
		"")
	querySpec.SetValue(fmt.Sprintf("QuerySpecification: (%s)", v.getText(ctx.BaseParserRuleContext)))

	v.setCtxLevels(v.SQL2AqlCtx, level-1, levelWith, levelQuery)
	return querySpec
}