Merge from match + load csv invalid behaviour

This commit is contained in:
Josip Mrden
2023-05-05 15:34:25 +02:00
parent 109150641c
commit 90d17f1bfd
6 changed files with 45 additions and 19 deletions

View File

@@ -4598,7 +4598,7 @@ LoadCsv::LoadCsv(std::shared_ptr<LogicalOperator> input, Expression *file, bool
MG_ASSERT(file_, "Something went wrong - '{}' member file_ shouldn't be a nullptr", __func__);
}
bool LoadCsv::Accept(HierarchicalLogicalOperatorVisitor &visitor) { return false; };
ACCEPT_WITH_INPUT(LoadCsv)
class LoadCsvCursor;
@@ -4649,14 +4649,12 @@ TypedValue CsvRowToTypedMap(csv::Reader::Row &row, csv::Reader::Header header) {
class LoadCsvCursor : public Cursor {
const LoadCsv *self_;
const UniqueCursorPtr input_cursor_;
bool input_is_once_;
bool did_pull_;
std::optional<csv::Reader> reader_{};
public:
LoadCsvCursor(const LoadCsv *self, utils::MemoryResource *mem)
: self_(self), input_cursor_(self_->input_->MakeCursor(mem)) {
input_is_once_ = dynamic_cast<Once *>(self_->input_.get());
}
: self_(self), input_cursor_(self_->input_->MakeCursor(mem)), did_pull_{false} {}
bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("LoadCsv");
@@ -4674,12 +4672,14 @@ class LoadCsvCursor : public Cursor {
bool input_pulled = input_cursor_->Pull(frame, context);
// If the input is Once, we have to keep going until we read all the rows,
// regardless of whether the pull on Once returned false.
// If we have e.g. MATCH(n) LOAD CSV ... AS x SET n.name = x.name, then we
// have to read at most cardinality(n) rows (but we can read less and stop
// pulling MATCH).
if (!input_is_once_ && !input_pulled) return false;
if (input_pulled) {
if (did_pull_) {
throw QueryRuntimeException(
"LOAD CSV can be executed only once, please check if the cardinality of the operator before LOAD CSV is 1");
}
did_pull_ = true;
}
auto row = reader_->GetNextRow(context.evaluation_context.memory);
if (!row) {
return false;

View File

@@ -874,11 +874,27 @@ bool PlanToJsonVisitor::PreVisit(query::plan::CallProcedure &op) {
bool PlanToJsonVisitor::PreVisit(query::plan::LoadCsv &op) {
json self;
self["name"] = "LoadCsv";
self["file"] = ToJson(op.file_);
self["with_header"] = op.with_header_;
self["ignore_bad"] = op.ignore_bad_;
self["delimiter"] = ToJson(op.delimiter_);
self["quote"] = ToJson(op.quote_);
if (op.file_) {
self["file"] = ToJson(op.file_);
}
if (op.with_header_) {
self["with_header"] = op.with_header_;
}
if (op.ignore_bad_) {
self["ignore_bad"] = op.ignore_bad_;
}
if (op.delimiter_) {
self["delimiter"] = ToJson(op.delimiter_);
}
if (op.quote_) {
self["quote"] = ToJson(op.quote_);
}
self["row_variable"] = ToJson(op.row_var_);
op.input_->Accept(*this);

View File

@@ -477,6 +477,16 @@ class IndexLookupRewriter final : public HierarchicalLogicalOperatorVisitor {
return true;
}
bool PreVisit(LoadCsv &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(LoadCsv & /*op*/) override {
prev_ops_.pop_back();
return true;
}
std::shared_ptr<LogicalOperator> new_root_;
private:

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source