Skip to content

关于on子句中or的处理问题 #31

@hmk114

Description

@hmk114

在yacc_sql.y中,on子句和where子句共用符号condition_list

condition_list:
/* empty */ {
$$ = nullptr;
} | condition {
$$ = new WhereConditions;
$$->conditions.emplace_back(*$1);
delete $1;
} | condition AND condition_list {
$$ = $3;
$$->type = ConjunctionType::AND;
$$->conditions.emplace_back(*$1);
delete $1;
} | condition OR condition_list {
$$ = $3;
$$->type = ConjunctionType::OR;
$$->conditions.emplace_back(*$1);
delete $1;
}
;

但是创建JoinSqlNode时,condition_list中的ConjunctionType type属性被丢弃了(JoinSqlNode中没有type字段):
join_list:
/* empty */
{
$$ = nullptr;
}
| INNER JOIN rel_alias join_conditions join_list{
if ($5 != nullptr) {
$$ = $5;
} else {
$$ = new std::vector<JoinSqlNode>;
}
JoinSqlNode* joinSqlNode = new JoinSqlNode;
joinSqlNode->relation = *$3;
if ($4 != nullptr) {
joinSqlNode->join_conditions.swap($4->conditions);
std::reverse(joinSqlNode->join_conditions.begin(), joinSqlNode->join_conditions.end());
}
delete $4;
$$->emplace_back(*joinSqlNode);
delete joinSqlNode;
delete $3;
}
;

最后,在创建select_stmt对象时,FilterStmt对象中的ConjunctionType conjunction_type_字段也未被赋值(后面对where和having子句的处理则正确进行了赋值):
std::vector<FilterStmt *> join_filter_stmts;
for (auto& join_list :select_sql.join_lists) {
FilterStmt *join_filter_stmt = nullptr;
rc = FilterStmt::create(db,
default_table,
&table_map,
join_list.join_conditions.data(),
static_cast<int>(join_list.join_conditions.size()),
join_filter_stmt);
join_filter_stmts.emplace_back(join_filter_stmt);
if (rc != RC::SUCCESS) {
LOG_WARN("cannot construct filter stmt");
return rc;
}
}

因此对于on中含有or的情况,目前的语法解析器虽然不会报错,但是解析结果并不能区分or和and两种不同的情况。
例如,下面两条语句会得到相同的语法树(都是and):

select * from join_table_1 inner join join_table_2 on join_table_1.id=join_table_2.id and join_table_2.num>13;
select * from join_table_1 inner join join_table_2 on join_table_1.id=join_table_2.id or join_table_2.num>13;

这容易引起困惑。如果是为了lab3实现方便,有意限制on条件仅能由and连接,或许应该在文档里更明确地说明一下,或者在语法解析时就限制不能出现or?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions