branch-2.1: [enhancement](nereids)remove dependence on old CreateTableStmt for CreateTableLikeCommand #48007 (#48528)
pick from master https://github.com/apache/doris/pull/48007 ### What problem does this PR solve? Issue Number: close #xxx Related PR: #xxx Problem Summary: ### Release note None ### Check List (For Author) - Test <!-- At least one of them must be included. --> - [ ] Regression test - [ ] Unit Test - [ ] Manual test (add detailed scripts or steps below) - [ ] No need to test or manual test. Explain why: - [ ] This is a refactor/code format and no logic has been changed. - [ ] Previous test can cover this change. - [ ] No code files have been changed. - [ ] Other reason <!-- Add your reason? --> - Behavior changed: - [ ] No. - [ ] Yes. <!-- Explain the behavior change --> - Does this need documentation? - [ ] No. - [ ] Yes. <!-- Add document PR link here. eg: https://github.com/apache/doris-website/pull/1214 --> ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label <!-- Add branch pick label that this PR should merge into -->
This commit is contained in:
@ -209,6 +209,10 @@ public class CreateTableCommand extends Command implements ForwardWithSync {
|
||||
return ctasQuery.isPresent();
|
||||
}
|
||||
|
||||
public Optional<LogicalPlan> getCtasQuery() {
|
||||
return ctasQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
|
||||
return visitor.visitCreateTableCommand(this, context);
|
||||
|
||||
@ -18,13 +18,27 @@
|
||||
package org.apache.doris.nereids.trees.plans.commands;
|
||||
|
||||
import org.apache.doris.analysis.CreateTableLikeStmt;
|
||||
import org.apache.doris.catalog.DatabaseIf;
|
||||
import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.catalog.TableIf;
|
||||
import org.apache.doris.common.DdlException;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.nereids.parser.NereidsParser;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
import org.apache.doris.nereids.trees.plans.commands.info.CreateTableInfo;
|
||||
import org.apache.doris.nereids.trees.plans.commands.info.CreateTableLikeInfo;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
import org.apache.doris.qe.StmtExecutor;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** CreateTableLikeCommand */
|
||||
public class CreateTableLikeCommand extends Command implements ForwardWithSync {
|
||||
private final CreateTableLikeInfo info;
|
||||
@ -39,11 +53,67 @@ public class CreateTableLikeCommand extends Command implements ForwardWithSync {
|
||||
executor.checkBlockRules();
|
||||
info.validate(ctx);
|
||||
CreateTableLikeStmt stmt = info.translateToLegacyStmt();
|
||||
Env.getCurrentEnv().createTableLike(stmt);
|
||||
doRun(stmt, ctx, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
|
||||
return visitor.visitCreateTableLikeCommand(this, context);
|
||||
}
|
||||
|
||||
private void doRun(CreateTableLikeStmt stmt, ConnectContext ctx, StmtExecutor executor) throws Exception {
|
||||
try {
|
||||
DatabaseIf db = Env.getCurrentInternalCatalog().getDbOrDdlException(stmt.getExistedDbName());
|
||||
TableIf table = db.getTableOrDdlException(stmt.getExistedTableName());
|
||||
|
||||
if (table.getType() == TableIf.TableType.VIEW) {
|
||||
throw new DdlException("Not support create table from a View");
|
||||
}
|
||||
|
||||
List<String> createTableStmt = Lists.newArrayList();
|
||||
table.readLock();
|
||||
try {
|
||||
if (table.isManagedTable()) {
|
||||
if (!CollectionUtils.isEmpty(stmt.getRollupNames())) {
|
||||
OlapTable olapTable = (OlapTable) table;
|
||||
for (String rollupIndexName : stmt.getRollupNames()) {
|
||||
if (!olapTable.hasMaterializedIndex(rollupIndexName)) {
|
||||
throw new DdlException("Rollup index[" + rollupIndexName + "] not exists in Table["
|
||||
+ olapTable.getName() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!CollectionUtils.isEmpty(stmt.getRollupNames()) || stmt.isWithAllRollup()) {
|
||||
throw new DdlException("Table[" + table.getName() + "] is external, not support rollup copy");
|
||||
}
|
||||
|
||||
Env.getDdlStmt(stmt, stmt.getDbName(), table, createTableStmt, null, null, false, false, true, -1L,
|
||||
false, false);
|
||||
if (createTableStmt.isEmpty()) {
|
||||
ErrorReport.reportDdlException(ErrorCode.ERROR_CREATE_TABLE_LIKE_EMPTY, "CREATE");
|
||||
}
|
||||
} finally {
|
||||
table.readUnlock();
|
||||
}
|
||||
|
||||
try {
|
||||
// analyze CreateTableStmt will check create_priv of existedTable, create table like only need
|
||||
// create_priv of newTable, and select_priv of existedTable, and priv check has done in
|
||||
// CreateTableStmt/CreateTableCommand, so we skip it
|
||||
ctx.setSkipAuth(true);
|
||||
NereidsParser nereidsParser = new NereidsParser();
|
||||
CreateTableCommand createTableCommand = (CreateTableCommand) nereidsParser
|
||||
.parseSingle(createTableStmt.get(0));
|
||||
CreateTableInfo createTableInfo = createTableCommand.getCreateTableInfo();
|
||||
createTableCommand = new CreateTableCommand(createTableCommand.getCtasQuery(),
|
||||
createTableInfo.withTableNameAndIfNotExists(stmt.getTableName(), stmt.isIfNotExists()));
|
||||
createTableCommand.run(ctx, executor);
|
||||
} finally {
|
||||
ctx.setSkipAuth(false);
|
||||
}
|
||||
} catch (UserException e) {
|
||||
throw new DdlException("Failed to execute CREATE TABLE LIKE " + stmt.getExistedTableName() + ". Reason: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +166,21 @@ public class CreateTableInfo {
|
||||
this.clusterKeysColumnNames = Utils.copyRequiredList(clusterKeyColumnNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* withTableNameAndIfNotExists
|
||||
*/
|
||||
public CreateTableInfo withTableNameAndIfNotExists(String tableName, boolean ifNotExists) {
|
||||
if (ctasColumns != null) {
|
||||
return new CreateTableInfo(ifNotExists, isExternal, ctlName, dbName, tableName, ctasColumns, engineName,
|
||||
keysType, keys, comment, partitionTableInfo, distribution, rollups, properties, extProperties,
|
||||
clusterKeysColumnNames);
|
||||
} else {
|
||||
return new CreateTableInfo(ifNotExists, isExternal, ctlName, dbName, tableName, columns, indexes,
|
||||
engineName, keysType, keys, comment, partitionTableInfo, distribution, rollups, properties,
|
||||
extProperties, clusterKeysColumnNames);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getCtasColumns() {
|
||||
return ctasColumns;
|
||||
}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
// 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.
|
||||
|
||||
// this suite is for creating table with timestamp datatype in defferent
|
||||
// case. For example: 'year' and 'Year' datatype should also be valid in definition
|
||||
|
||||
suite("test_create_table_like") {
|
||||
multi_sql """
|
||||
DROP TABLE IF EXISTS test_create_table_like_t1;
|
||||
CREATE TABLE `test_create_table_like_t1` (
|
||||
`id` int NULL,
|
||||
`m_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=OLAP
|
||||
UNIQUE KEY(`id`)
|
||||
DISTRIBUTED BY HASH(`id`) BUCKETS AUTO
|
||||
PROPERTIES (
|
||||
"replication_allocation" = "tag.location.default: 1"
|
||||
);
|
||||
DROP TABLE IF EXISTS test_create_table_like_t2;
|
||||
CREATE TABLE test_create_table_like_t2 like test_create_table_like_t1;
|
||||
"""
|
||||
}
|
||||
Reference in New Issue
Block a user