/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.lens.cube.parse; import java.util.Map; import java.util.Objects; import java.util.Set; import org.apache.lens.cube.metadata.CubeInterface; import org.apache.lens.cube.metadata.Dimension; import org.apache.lens.server.api.error.LensException; import org.apache.hadoop.hive.ql.parse.ASTNode; import org.apache.hadoop.hive.ql.parse.HiveParser; import org.antlr.runtime.CommonToken; import lombok.Getter; /** * Created on 31/03/17. */ public class StorageCandidateHQLContext extends DimHQLContext { @Getter private StorageCandidate storageCandidate; private CubeQueryContext rootCubeQueryContext; StorageCandidateHQLContext(StorageCandidate storageCandidate, Map<Dimension, CandidateDim> dimsToQuery, QueryAST ast, CubeQueryContext rootCubeQueryContext) throws LensException { super(storageCandidate.getCubeQueryContext(), dimsToQuery, ast); this.storageCandidate = storageCandidate; this.rootCubeQueryContext = rootCubeQueryContext; getCubeQueryContext().addRangeClauses(this); if (!isRoot()) { getQueryAst().setHavingAST(null); } } private boolean isRoot() { return Objects.equals(getCubeQueryContext(), rootCubeQueryContext) && Objects.equals(getStorageCandidate(), getCubeQueryContext().getPickedCandidate()); } public CubeQueryContext getCubeQueryContext() { return storageCandidate.getCubeQueryContext(); } public void updateFromString() throws LensException { String alias = getCubeQueryContext().getAliasForTableName(getCube().getName()); setFrom(storageCandidate.getAliasForTable(alias)); if (getCubeQueryContext().isAutoJoinResolved()) { setFrom(getCubeQueryContext().getAutoJoinCtx().getFromString( getFrom(), this, getDimsToQuery(), getCubeQueryContext())); } } CubeInterface getCube() { return storageCandidate.getCubeQueryContext().getCube(); } @Override protected String getFromTable() throws LensException { if (storageCandidate.getCubeQueryContext().isAutoJoinResolved()) { return getFrom(); } else { return storageCandidate.getCubeQueryContext().getQBFromString(storageCandidate, getDimsToQuery()); } } @Override public void updateDimFilterWithFactFilter() throws LensException { if (!getStorageCandidate().getStorageName().isEmpty()) { String qualifiedStorageTable = getStorageCandidate().getStorageName(); String storageTable = qualifiedStorageTable.substring(qualifiedStorageTable.indexOf(".") + 1); String where = getCubeQueryContext().getWhere(this, getCubeQueryContext().getAutoJoinCtx(), getQueryAst().getWhereAST(), getCubeQueryContext().getAliasForTableName(getStorageCandidate().getBaseTable().getName()), getCubeQueryContext().shouldReplaceDimFilterWithFactFilter(), storageTable, getDimsToQuery()); setWhere(where); } } private void updateAnswerableSelectColumns() throws LensException { // update select AST with selected fields int currentChild = 0; for (int i = 0; i < getCubeQueryContext().getSelectAST().getChildCount(); i++) { ASTNode selectExpr = (ASTNode) queryAst.getSelectAST().getChild(currentChild); Set<String> exprCols = HQLParser.getColsInExpr(getCubeQueryContext().getAliasForTableName(getCube()), selectExpr); if (getStorageCandidate().getColumns().containsAll(exprCols)) { ASTNode aliasNode = HQLParser.findNodeByPath(selectExpr, HiveParser.Identifier); String alias = getCubeQueryContext().getSelectPhrases().get(i).getSelectAlias(); if (aliasNode != null) { String queryAlias = aliasNode.getText(); if (!queryAlias.equals(alias)) { // replace the alias node ASTNode newAliasNode = new ASTNode(new CommonToken(HiveParser.Identifier, alias)); queryAst.getSelectAST().getChild(currentChild) .replaceChildren(selectExpr.getChildCount() - 1, selectExpr.getChildCount() - 1, newAliasNode); } } else { // add column alias ASTNode newAliasNode = new ASTNode(new CommonToken(HiveParser.Identifier, alias)); queryAst.getSelectAST().getChild(currentChild).addChild(newAliasNode); } } else { queryAst.getSelectAST().deleteChild(currentChild); currentChild--; } currentChild++; } } @Override protected void setMissingExpressions() throws LensException { setFrom(getFromTable()); setWhere(genWhereClauseWithDimPartitions(getWhere())); if (isRoot()) { if (Objects.equals(getStorageCandidate(), getCubeQueryContext().getPickedCandidate())) { updateAnswerableSelectColumns(); // Check if the picked candidate is a StorageCandidate and in that case // update the selectAST with final alias. CandidateUtil.updateFinalAlias(queryAst.getSelectAST(), getCubeQueryContext()); CandidateUtil.updateOrderByWithFinalAlias(queryAst.getOrderByAST(), queryAst.getSelectAST()); setPrefix(getCubeQueryContext().getInsertClause()); } } } }