加载时转换
概要
支持从 Stage 复制到表时进行转换。
动机
目前,我们支持 Stage 表函数,因此我们可以在从 Stage 插入到表时进行转换。
insert into table1 from (select c1, c2 from @stage1/path/to/dir);
但这仍然缺少 COPY INTO
的一个功能:增量加载(记住已加载的文件)。
COPY INTO <table>
现在仅支持 FROM <STAGE>
。
指导性解释
支持像这样的 copy into:
COPY into table1 from (select c1, c2 from @stage1/path/to/dir where c3 > 1);
对子查询部分的限制:
- 仅包含一个基本表。
- 不允许聚合,因为插入的每个记录都应属于某个文件。
- 由于先前的 2 个限制,可以合理地说不需要嵌套子查询,我们可以选择禁止它。
自动转换
如果满足 auto_cast_rule,则子查询的输出表达式应转换为表的 schema。
可以优化掉一些转换。例如:
对于 COPY into table1 from (select c1::string from @stage1/path/to/dir);
,其中 c1 是 int,
我们可以直接将 c1 解析为字符串。
如果 c1 的目标列也是 int,则可以删除 '::string'。
优化
投影和过滤:
- 对于像 Parquet 这样的文件格式,列剪裁和过滤下推可以很好地工作。
- 对于其他格式,如 CSV/TSV/NDJSON,有机会快速解析未使用的列,例如对于 TSV,
我们可以在解析完投影中的最后一个字段后直接跳转到下一个
\n
。
参考级解释
COPY into <table> from (select <expr> from @<stage>/<path>(<options>) <alias> where <expr>);
原理和替代方案
一些其他功能可用于“加载时转换”,但仅在有限的情况下:
自动转换
如果源 schema 可以自动转换为目标 schema,则不应需要 SQL 中的显式转换。 现在,一些“转换”由解析器实现,只要使用提供目标类型,如 RFC: Stage With Schema 中所示 例如,Timestamp Type 解 码器可以接受数字和字符串。
我们应该稍后改进这一点。在此之前,用户可以使用此 RFC 中的方法来完成相同的功能。
FileFormatOptions
例如,某些数据库对 CSV 文件格式有一个选项 TRIM
。但用户可能需要不同的变体
- 修剪开头或结尾空格?还是两者都修剪?
- 在引号内还是在引号外?
- 应用于某些列?空格对于某些列可能是有意义的。