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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions