Increments the counter and returns the old counter.
| 95 | |
| 96 | /// Increments the counter and returns the old counter. |
| 97 | [[nodiscard]] UInt64 update(String series_name, UInt64 start_value, size_t & current_series, UInt64 increment, zkutil::ZooKeeperPtr & keeper) const |
| 98 | { |
| 99 | if (series_name.empty()) |
| 100 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "The first argument of function {} (the series name) cannot be empty", name); |
| 101 | series_name = escapeForFileName(series_name); |
| 102 | if (series_name.size() > 100) /// Arbitrary safety threshold |
| 103 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Series name '{}' is too long", series_name); |
| 104 | |
| 105 | String serial_path = std::filesystem::path(keeper_path) / series_name; |
| 106 | |
| 107 | if (current_series < max_series) |
| 108 | { |
| 109 | const auto initial_value = toString(start_value); |
| 110 | auto code = keeper->tryCreate(serial_path, initial_value, zkutil::CreateMode::Persistent); |
| 111 | if (code == Coordination::Error::ZOK) |
| 112 | ++current_series; |
| 113 | else if (code != Coordination::Error::ZNODEEXISTS) |
| 114 | throw zkutil::KeeperException::fromPath(code, serial_path); |
| 115 | } |
| 116 | else |
| 117 | { |
| 118 | if (!keeper->exists(serial_path)) |
| 119 | throw Exception(ErrorCodes::LIMIT_EXCEEDED, |
| 120 | "Too many series created by {} function, maximum: {}. This is controlled by the `max_autoincrement_series` setting.", |
| 121 | name, max_series); |
| 122 | } |
| 123 | |
| 124 | UInt64 counter = 0; |
| 125 | Coordination::Stat stat; |
| 126 | while (true) |
| 127 | { |
| 128 | String old_value = keeper->get(serial_path, &stat); |
| 129 | counter = parse<UInt64>(old_value); |
| 130 | String new_value = toString(counter + increment); |
| 131 | auto code = keeper->trySet(serial_path, new_value, stat.version); |
| 132 | |
| 133 | if (code == Coordination::Error::ZOK) |
| 134 | break; |
| 135 | |
| 136 | if (code == Coordination::Error::ZBADVERSION) |
| 137 | continue; |
| 138 | |
| 139 | throw zkutil::KeeperException::fromPath(code, serial_path); |
| 140 | } |
| 141 | |
| 142 | return counter; |
| 143 | } |
| 144 | |
| 145 | ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override |
| 146 | { |
no test coverage detected