MTMVUtil.java
// 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.doris.mtmv;
import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.MTMV;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.TableIf;
import org.apache.doris.catalog.TableIf.TableType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.MetaNotFoundException;
import org.apache.doris.common.util.TimeUtils;
import org.apache.doris.datasource.CatalogMgr;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.qe.ConnectContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public class MTMVUtil {
/**
* get Table by BaseTableInfo
*
* @param baseTableInfo
* @return
* @throws AnalysisException
*/
public static TableIf getTable(BaseTableInfo baseTableInfo) throws AnalysisException {
// for compatible old version, not have name
if (StringUtils.isEmpty(baseTableInfo.getCtlName())) {
return Env.getCurrentEnv().getCatalogMgr()
.getCatalogOrAnalysisException(baseTableInfo.getCtlId())
.getDbOrAnalysisException(baseTableInfo.getDbId())
.getTableOrAnalysisException(baseTableInfo.getTableId());
} else {
return Env.getCurrentEnv().getCatalogMgr()
.getCatalogOrAnalysisException(baseTableInfo.getCtlName())
.getDbOrAnalysisException(baseTableInfo.getDbName())
.getTableOrAnalysisException(baseTableInfo.getTableName());
}
}
public static MTMVRelatedTableIf getRelatedTable(BaseTableInfo baseTableInfo) {
TableIf relatedTable = null;
try {
relatedTable = MTMVUtil.getTable(baseTableInfo);
} catch (org.apache.doris.common.AnalysisException e) {
throw new org.apache.doris.nereids.exceptions.AnalysisException(e.getMessage(), e);
}
if (!(relatedTable instanceof MTMVRelatedTableIf)) {
throw new org.apache.doris.nereids.exceptions.AnalysisException(
"base table for partitioning only can be OlapTable or HMSTable");
}
return (MTMVRelatedTableIf) relatedTable;
}
public static MTMV getMTMV(long dbId, long mtmvId) throws DdlException, MetaNotFoundException {
Database db = Env.getCurrentInternalCatalog().getDbOrDdlException(dbId);
return (MTMV) db.getTableOrMetaException(mtmvId, TableType.MATERIALIZED_VIEW);
}
/**
* if base tables of mtmv contains external table
*
* @param mtmv
* @return
*/
public static boolean mtmvContainsExternalTable(MTMV mtmv) {
Set<BaseTableInfo> baseTables = mtmv.getRelation().getBaseTablesOneLevel();
for (BaseTableInfo baseTableInfo : baseTables) {
if (!baseTableInfo.isInternalTable()) {
return true;
}
}
return false;
}
/**
* Convert LiteralExpr to second
*
* @param expr
* @param dateFormatOptional
* @return
* @throws AnalysisException
*/
public static long getExprTimeSec(org.apache.doris.analysis.LiteralExpr expr, Optional<String> dateFormatOptional)
throws AnalysisException {
if (expr instanceof org.apache.doris.analysis.MaxLiteral) {
return Long.MAX_VALUE;
}
if (expr instanceof org.apache.doris.analysis.NullLiteral) {
return Long.MIN_VALUE;
}
if (expr instanceof org.apache.doris.analysis.DateLiteral) {
return ((org.apache.doris.analysis.DateLiteral) expr).unixTimestamp(TimeUtils.getTimeZone()) / 1000;
}
if (!dateFormatOptional.isPresent()) {
throw new AnalysisException("expr is not DateLiteral and DateFormat is not present.");
}
String dateFormat = dateFormatOptional.get();
Expression strToDate = DateTimeExtractAndTransform
.strToDate(new VarcharLiteral(expr.getStringValue()), new VarcharLiteral(dateFormat));
if (strToDate instanceof DateTimeV2Literal) {
return ((IntegerLiteral) DateTimeExtractAndTransform
.unixTimestamp((DateTimeV2Literal) strToDate)).getValue();
} else if (strToDate instanceof DateV2Literal) {
return ((IntegerLiteral) DateTimeExtractAndTransform
.unixTimestamp((DateV2Literal) strToDate)).getValue();
} else {
throw new AnalysisException(
String.format("strToDate failed, stringValue: %s, dateFormat: %s",
expr.getStringValue(), dateFormat));
}
}
public static boolean allowModifyMTMVData(ConnectContext ctx) {
if (ctx == null) {
return false;
}
return ctx.getSessionVariable().isAllowModifyMaterializedViewData();
}
public static void checkModifyMTMVData(Database db, List<Long> tableIdList, ConnectContext ctx)
throws AnalysisException {
if (CollectionUtils.isEmpty(tableIdList)) {
return;
}
for (long tableId : tableIdList) {
Optional<Table> table = db.getTable(tableId);
if (table.isPresent() && table.get() instanceof MTMV && !MTMVUtil.allowModifyMTMVData(ctx)) {
throw new AnalysisException("Not allowed to perform current operation on async materialized view");
}
}
}
public static void compatibleMTMV(CatalogMgr catalogMgr) {
List<Database> dbs = catalogMgr.getInternalCatalog().getDbs();
for (Database database : dbs) {
List<Table> tables = database.getTables();
for (Table table : tables) {
if (table instanceof MTMV) {
((MTMV) table).compatible(catalogMgr);
}
}
}
}
}