ViewCreatorFactory 是dremio 中专门管理view 的,目前主要是对于space 以及home 中的处理,当然对于source 也是可以支持的(支持版本类型的,比如nessie,原始分布式文件系统的实际也是可以支持的,但是不太符合dremio的玩法,以及限定死了)
调用部分
实际上通过标准的sqlhandler,具体实现就是CreateViewHandler
- 参考代码
CreateViewHandler.java
public List<SimpleCommandResult> toResult(String sql, SqlNode sqlNode) throws Exception {
SqlCreateView createView = SqlNodeUtil.unwrap(sqlNode, SqlCreateView.class);
ParserUtil.validateParsedViewQuery(createView.getQuery());
final NamespaceKey resolvedViewPath = catalog.resolveSingle(createView.getPath());
Preconditions.checkState(resolvedViewPath.size() > 1, "View path "+ resolvedViewPath + " is not valid ");
String formattedViewSql = getViewSql(createView, sql);
VersionContext statementSourceVersion =
ReferenceTypeUtils.map(createView.getRefType(), createView.getRefValue(), null);
final VersionContext sessionVersion = config.getContext().getSession().getSessionVersionForSource(resolvedViewPath.getRoot());
ConvertedRelNode convertedRelNode = validateTablesAndVersionContext(createView.getQuery(), resolvedViewPath, statementSourceVersion.orElse(sessionVersion));
catalog.validatePrivilege(resolvedViewPath, SqlGrant.Privilege.ALTER);
if (isVersioned(resolvedViewPath)) {
return createVersionedView(createView, formattedViewSql, convertedRelNode, resolvedViewPath);
} else {
return createView(createView, formattedViewSql, convertedRelNode, resolvedViewPath);
}
}
SqlCreateView createView = SqlNodeUtil.unwrap(sqlNode, SqlCreateView.class);
createView参考处理
- 代码
CatalogImpl.java
public void createView(final NamespaceKey key, View view, ViewOptions viewOptions, NamespaceAttribute... attributes) throws IOException {
// 会判断不同的类型,比如source,space,home
switch (getType(key, true)) {
case SOURCE:
asMutable(key, "does not support create view")
.createOrUpdateView(key, options.getSchemaConfig(), view, viewOptions);
break;
case SPACE:
case HOME:
if (view.hasDeclaredFieldNames()) {
throw UserException.unsupportedError()
.message("Dremio doesn't support field aliases defined in view creation.")
.buildSilently();
}
// 对于space 以及home 都使用了viewCreatorFactory 进行view 的操作,具体的实现是DACViewCreatorFactory
viewCreatorFactory.get(userName)
.createView(key.getPathComponents(), view.getSql(), view.getWorkspaceSchemaPath(), false, attributes);
break;
default:
throw UserException.unsupportedError()
.message("Cannot create view in %s.", key)
.build(logger);
}
}
// 会判断不同的类型,比如source,space,home
DACViewCreatorFactory的处理
- 初始化
DACDaemonModule 模块中
参考代码
registry.bind(
ViewCreatorFactory.class,
new DACViewCreatorFactory(
registry.provider(InitializerRegistry.class),
registry.provider(LegacyKVStoreProvider.class),
registry.provider(JobsService.class),
registry.provider(NamespaceService.Factory.class),
registry.provider(CatalogService.class),
registry.provider(ContextService.class),
() -> bootstrap.getAllocator()
)
);
ViewCreatorFactory.class,
- createView 处理
DACViewCreatorFactory 实现了ViewCreatorFactory 的接口定义,我只简单说明下createView 的处理
public void createView(List<String> path, String sql, List<String> sqlContext, boolean isVersionedSource, NamespaceAttribute... attributes) {
SecurityContext securityContext = getSecurityContext();
QueryExecutor executor = new QueryExecutor(jobsService, null, securityContext);
DatasetTool tool = newDatasetTool(securityContext, executor);
try {
DatasetVersion version = DatasetVersion.newVersion();
DatasetPath datasetPath = new DatasetPath(path);
// DatasetTool 会进行view dataset 的创建,只是默认title为空,同时加载预览数据
InitialPreviewResponse response = tool.newUntitled(allocator, new FromSQL(sql), version, sqlContext, null,true, 0, true);
DatasetPath tmpPath = new DatasetPath(response.getDataset().getFullPath());
VirtualDatasetUI vds = datasetService.getVersion(tmpPath, response.getDataset().getDatasetVersion(), isVersionedSource);
// TODO - Remove dependency on a Resource file.
// 此处使用了一个DatasetVersionResource,不太好,上边的todo 也说明了
newDatasetVersionResource(securityContext, tool, version, tmpPath, allocator).save(vds, datasetPath, null, null, isVersionedSource, attributes);
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
SecurityContext securityContext = getSecurityContext();
说明
dremio 推荐的玩法是基于view 的vds 处理,使用了ViewCreatorFactory,核心是space 以及home 类型的,当然对于支持多版本的source 也是支持的(nessie ),以上是一个简单说明,详细的可以参考个github 源码(比如CreateViewHandler 执行的)
参考资料
sabot/kernel/src/main/java/com/dremio/exec/catalog/ViewCreatorFactory.java
dac/backend/src/main/java/com/dremio/dac/service/datasets/DACViewCreatorFactory.java
sabot/kernel/src/main/java/com/dremio/exec/catalog/CatalogImpl.java
sabot/kernel/src/main/java/com/dremio/exec/planner/sql/parser/SqlCreateView.java
sabot/kernel/src/main/java/com/dremio/exec/server/SabotContext.java
sabot/kernel/src/main/java/com/dremio/exec/planner/sql/handlers/direct/CreateViewHandler.java
sabot/kernel/src/main/java/com/dremio/exec/planner/sql/handlers/commands/CommandCreator.java
sabot/kernel/src/main/java/com/dremio/exec/work/foreman/AttemptManager.java
dac/backend/src/main/java/com/dremio/dac/explore/QueryExecutor.java
dac/backend/src/main/java/com/dremio/dac/explore/DatasetTool.java
dac/backend/src/main/java/com/dremio/dac/service/datasets/DatasetVersionMutator.java