Skip to content

Commit

Permalink
feat(parser): new SQL for create table (#46)
Browse files Browse the repository at this point in the history
CREATE TABLE t1 LIKE PARQUET 'hdfs://path'
  • Loading branch information
aceforeverd authored Jan 11, 2023
1 parent 96dca44 commit 057e680
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 2 deletions.
3 changes: 2 additions & 1 deletion zetasql/parser/ast_node_kind.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ enum ASTNodeKind {
AST_WINDOW_ATTRIBUTE_EXCLUDE_CURRENT_ROW,
AST_WINDOW_ATTRIBUTE_INST_NOT_IN_WINDOW,
AST_WINDOW_ATTRIBUTE_LIST,
kLastASTNodeKind = AST_WINDOW_ATTRIBUTE_LIST,
AST_LIKE_TABLE_CLAUSE,
kLastASTNodeKind = AST_LIKE_TABLE_CLAUSE,
};

} // namespace zetasql
Expand Down
17 changes: 16 additions & 1 deletion zetasql/parser/bison_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ using zetasql::ASTDropStatement;
%token KW_OPTIONS "OPTIONS"
%token KW_OUT "OUT"
%token KW_OUTFILE "OUTFILE"
%token KW_PARQUET "PARQUET"
%token KW_PERCENT "PERCENT"
%token KW_PIVOT "PIVOT"
%token KW_POLICIES "POLICIES"
Expand Down Expand Up @@ -1185,6 +1186,7 @@ using zetasql::ASTDropStatement;
%type <node> opt_language
%type <node> opt_like_string_literal
%type <node> opt_like_path_expression
%type <node> opt_like_in_create_table
%type <node> opt_limit_offset_clause
%type <node> opt_config_clause
%type <node> opt_maxsize
Expand Down Expand Up @@ -2553,7 +2555,7 @@ create_table_function_statement:
create_table_statement:
"CREATE" opt_or_replace opt_create_scope "TABLE" opt_if_not_exists
maybe_dashed_path_expression opt_table_element_list
opt_like_path_expression opt_clone_table
opt_like_in_create_table opt_clone_table
opt_partition_by_clause_no_hint opt_cluster_by_clause_no_hint
opt_options_list opt_as_query
{
Expand Down Expand Up @@ -3652,6 +3654,18 @@ opt_like_path_expression:
| /* Nothing */ { $$ = nullptr; }
;

opt_like_in_create_table:
"LIKE" maybe_dashed_path_expression
{
$$ = $2;
}
| "LIKE" "PARQUET" string_literal
{
$$ = MAKE_NODE(ASTLikeTableClause, @$, {$3});
}
| /* Nothing */ { $$ = nullptr; }
;

opt_clone_table:
"CLONE" clone_data_source
{
Expand Down Expand Up @@ -7531,6 +7545,7 @@ keyword_as_identifier:
| "OPTIONS"
| "OUT"
| "OUTFILE"
| "PARQUET"
| "PERCENT"
| "PIVOT"
| "POLICIES"
Expand Down
1 change: 1 addition & 0 deletions zetasql/parser/flex_tokenizer.l
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ out { return BisonParserImpl::token::KW_OUT; }
outfile { return BisonParserImpl::token::KW_OUTFILE; };
outer { return BisonParserImpl::token::KW_OUTER; }
over { return BisonParserImpl::token::KW_OVER; }
parquet { return BisonParserImpl::token::KW_PARQUET; }
partition { return BisonParserImpl::token::KW_PARTITION; }
percent { return BisonParserImpl::token::KW_PERCENT; }
policies { return BisonParserImpl::token::KW_POLICIES; }
Expand Down
1 change: 1 addition & 0 deletions zetasql/parser/keywords.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ constexpr KeywordInfoPOD kAllKeywords[] = {
{"outfile", KW_OUTFILE},
{"outer", KW_OUTER, KeywordInfo::kReserved},
{"over", KW_OVER, KeywordInfo::kReserved},
{"parquet", KW_PARQUET},
{"partition", KW_PARTITION, KeywordInfo::kReserved},
{"percent", KW_PERCENT},
{"pivot", KW_PIVOT},
Expand Down
10 changes: 10 additions & 0 deletions zetasql/parser/parse_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ static absl::flat_hash_map<ASTNodeKind, std::string> CreateNodeNamesMap() {
map[AST_WINDOW_ATTRIBUTE_EXCLUDE_CURRENT_ROW] = "WindowAttributeExcludeCurrentRow";
map[AST_WINDOW_ATTRIBUTE_INST_NOT_IN_WINDOW] = "WindowAttributeInstNotInWindow";
map[AST_WINDOW_ATTRIBUTE_LIST] = "WindowAttributeList";
map[AST_LIKE_TABLE_CLAUSE] = "LikeTableClause";
for (int kind = kFirstASTNodeKind; kind <= kLastASTNodeKind;
++kind) {
ZETASQL_DCHECK(zetasql_base::ContainsKey(map, static_cast<ASTNodeKind>(kind)))
Expand Down Expand Up @@ -1687,4 +1688,13 @@ absl::string_view SchemaObjectKindToName(SchemaObjectKind schema_object_kind) {
}
}

std::string ASTLikeTableClause::SingleNodeDebugString() const {
auto result = ASTNode::SingleNodeDebugString();
switch (kind()) {
case PARQUET:
absl::StrAppend(&result, "(PARQUET)");
}
return result;
}

} // namespace zetasql
32 changes: 32 additions & 0 deletions zetasql/parser/parse_tree_manual.h
Original file line number Diff line number Diff line change
Expand Up @@ -4586,6 +4586,33 @@ class ASTCreateTableFunctionStatement final : public ASTCreateFunctionStmtBase {
const ASTQuery* query_ = nullptr;
};

// create table <table_name> like PARQUET '...'
// - create table LIKE <table_name> is not covered by this class
class ASTLikeTableClause final : public ASTNode {
public:
static constexpr ASTNodeKind kConcreteNodeKind = AST_LIKE_TABLE_CLAUSE;
enum TableKind { PARQUET };

ASTLikeTableClause() : ASTNode(kConcreteNodeKind) {}
void Accept(ParseTreeVisitor* visitor, void* data) const override;
zetasql_base::StatusOr<VisitResult> Accept(
NonRecursiveParseTreeVisitor* visitor) const override;
std::string SingleNodeDebugString() const override;

auto kind() const { return kind_; }
void set_kind(TableKind k) { kind_ = k; }
auto path() const { return path_; }

private:
void InitFields() final {
FieldLoader fl(this);
fl.AddRequired(&path_);
}

TableKind kind_ = PARQUET;
const ASTStringLiteral* path_;
};

class ASTCreateTableStmtBase : public ASTCreateStatement {
public:
explicit ASTCreateTableStmtBase(const ASTNodeKind kConcreteNodeKind)
Expand Down Expand Up @@ -4619,6 +4646,9 @@ class ASTCreateTableStatement final : public ASTCreateTableStmtBase {
const ASTCloneDataSource* clone_data_source() const {
return clone_data_source_;
}
// optional like clause for `LIKE PARQUET '...'` in create table
// use like_table_name() instead for `LIKE <path-expression>`
auto like_table_clause() const { return like_table_clause_; }
const ASTPartitionBy* partition_by() const { return partition_by_; }
const ASTClusterBy* cluster_by() const { return cluster_by_; }
const ASTQuery* query() const { return query_; }
Expand All @@ -4629,6 +4659,7 @@ class ASTCreateTableStatement final : public ASTCreateTableStmtBase {
fl.AddRequired(&name_);
fl.AddOptional(&table_element_list_, AST_TABLE_ELEMENT_LIST);
fl.AddOptional(&like_table_name_, AST_PATH_EXPRESSION);
fl.AddOptional(&like_table_clause_, AST_LIKE_TABLE_CLAUSE);
fl.AddOptional(&clone_data_source_, AST_CLONE_DATA_SOURCE);
fl.AddOptional(&partition_by_, AST_PARTITION_BY);
fl.AddOptional(&cluster_by_, AST_CLUSTER_BY);
Expand All @@ -4640,6 +4671,7 @@ class ASTCreateTableStatement final : public ASTCreateTableStmtBase {
const ASTPartitionBy* partition_by_ = nullptr; // May be NULL.
const ASTClusterBy* cluster_by_ = nullptr; // May be NULL.
const ASTQuery* query_ = nullptr; // May be NULL.
const ASTLikeTableClause* like_table_clause_ = nullptr; // May be NULL.
};

class ASTCreateEntityStatement final : public ASTCreateStatement {
Expand Down
42 changes: 42 additions & 0 deletions zetasql/parser/testdata/create_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -2777,6 +2777,48 @@ CREATE TABLE t
t1
==

# CREATE TABLE LIKE PARQUET '...'
create table t LIKE PARQUET 'hdfs://path';
--
CreateTableStatement [0-41]
PathExpression [13-14]
Identifier(t) [13-14]
LikeTableClause(PARQUET) [15-41]
StringLiteral('hdfs://path') [28-41]
--
CREATE TABLE t LIKE
PARQUET 'hdfs://path'
==

# CREATE TABLE LIKE PARQUET, 'PARQUET' become like table name
create table t LIKE PARQUET;
--
CreateTableStatement [0-27]
PathExpression [13-14]
Identifier(t) [13-14]
PathExpression [20-27]
Identifier(PARQUET) [20-27]
--
CREATE TABLE t LIKE
PARQUET
==

# ERROR: CREATE TABLE LIKE PARXX '...'
create table t LIKE PARXX 'hdfs://path';
--
ERROR: Syntax error: Expected end of input but got string literal 'hdfs://path' [at 1:27]
create table t LIKE PARXX 'hdfs://path';
^
==

# ERROR: CREATE TABLE LIKE '...'
create table t LIKE 'hdfs://path';
--
ERROR: Syntax error: Unexpected string literal 'hdfs://path' [at 1:21]
create table t LIKE 'hdfs://path';
^
==

# CREATE TABLE LIKE without table name.
create table t like;
--
Expand Down
15 changes: 15 additions & 0 deletions zetasql/parser/unparser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ void Unparser::visitASTCreateTableStatement(
println("LIKE");
node->like_table_name()->Accept(this, data);
}
if (node->like_table_clause()) {
node->like_table_clause()->Accept(this, data);
}
if (node->clone_data_source() != nullptr) {
println("CLONE");
node->clone_data_source()->Accept(this, data);
Expand Down Expand Up @@ -2237,6 +2240,18 @@ void Unparser::visitASTWindowAttributeInstNotInWindow(
print("INSTANCE_NOT_IN_WINDOW");
}

void Unparser::visitASTLikeTableClause(const ASTLikeTableClause *node,
void *data) {
println("LIKE");
switch (node->kind()) {
case ASTLikeTableClause::PARQUET: {
print("PARQUET");
break;
}
}
node->path()->Accept(this, data);
}

void Unparser::visitASTPartitionBy(const ASTPartitionBy* node, void* data) {
print("PARTITION");
if (node->hint() != nullptr) {
Expand Down
2 changes: 2 additions & 0 deletions zetasql/parser/unparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ class Unparser : public ParseTreeVisitor {
const ASTWindowAttributeExcludeCurrentRow *node, void *data) override;
void visitASTWindowAttributeInstNotInWindow(
const ASTWindowAttributeInstNotInWindow *node, void *data) override;
void visitASTLikeTableClause(const ASTLikeTableClause *node,
void *data) override;
void visitASTPartitionBy(const ASTPartitionBy* node, void* data) override;
void visitASTClusterBy(const ASTClusterBy* node, void* data) override;
void visitASTCloneDataSource(const ASTCloneDataSource* node,
Expand Down

0 comments on commit 057e680

Please sign in to comment.