| 152 | } |
| 153 | |
| 154 | Status TCatalogObjectFromObjectName(const TCatalogObjectType::type& object_type, |
| 155 | const string& object_name, TCatalogObject* catalog_object) { |
| 156 | // See Catalog::toCatalogObjectKey in Catalog.java for more information on the |
| 157 | // catalog object key format. |
| 158 | switch (object_type) { |
| 159 | case TCatalogObjectType::DATABASE: |
| 160 | catalog_object->__set_type(object_type); |
| 161 | catalog_object->__set_db(TDatabase()); |
| 162 | catalog_object->db.__set_db_name(object_name); |
| 163 | break; |
| 164 | case TCatalogObjectType::TABLE: |
| 165 | case TCatalogObjectType::VIEW: { |
| 166 | catalog_object->__set_type(object_type); |
| 167 | catalog_object->__set_table(TTable()); |
| 168 | // Parse what should be a fully qualified table name |
| 169 | int pos = object_name.find('.'); |
| 170 | if (pos == string::npos || pos >= object_name.size() - 1) { |
| 171 | stringstream error_msg; |
| 172 | error_msg << "Invalid table name: " << object_name; |
| 173 | return Status(error_msg.str()); |
| 174 | } |
| 175 | catalog_object->table.__set_db_name(object_name.substr(0, pos)); |
| 176 | catalog_object->table.__set_tbl_name(object_name.substr(pos + 1)); |
| 177 | break; |
| 178 | } |
| 179 | case TCatalogObjectType::HDFS_PARTITION: { |
| 180 | catalog_object->__set_type(object_type); |
| 181 | catalog_object->__set_hdfs_partition(THdfsPartition()); |
| 182 | // Parse format: dbName.tableName:partitionName |
| 183 | // The partitionName format is "key1=value1/key2=value2/..." |
| 184 | // If partition values contain special characters (like '/'), they must be |
| 185 | // double-encoded in the HTTP request URL because: |
| 186 | // 1. Hive stores such partitions on HDFS with '/' pre-encoded as '%2F' |
| 187 | // (e.g., directory name: ds=2024%2F12%2F25) |
| 188 | // 2. HTTP URL encoding must encode the '%' character as '%25' |
| 189 | // (e.g., HTTP URL: ds=2024%252F12%252F25) |
| 190 | // Example: For partition value "12/25/2025", the URL should contain: |
| 191 | // "ds=12%252F25%252F2025" (double-encoded) |
| 192 | // After URL decoding, the backend receives: "ds=12%2F25%2F2025" |
| 193 | // After FileUtils.unescapePathName(), the value is: "12/25/2025" |
| 194 | int dot_pos = object_name.find('.'); |
| 195 | int colon_pos = object_name.find(':'); |
| 196 | if (dot_pos == string::npos || dot_pos >= object_name.size() - 1 |
| 197 | || colon_pos == string::npos || colon_pos >= object_name.size() - 1 |
| 198 | || colon_pos <= dot_pos || dot_pos == 0) { |
| 199 | stringstream error_msg; |
| 200 | error_msg << "Invalid partition name: " << object_name; |
| 201 | return Status(error_msg.str()); |
| 202 | } |
| 203 | catalog_object->hdfs_partition.__set_db_name(object_name.substr(0, dot_pos)); |
| 204 | catalog_object->hdfs_partition.__set_tbl_name( |
| 205 | object_name.substr(dot_pos + 1, colon_pos - dot_pos - 1)); |
| 206 | catalog_object->hdfs_partition.__set_partition_name( |
| 207 | object_name.substr(colon_pos + 1)); |
| 208 | break; |
| 209 | } |
| 210 | case TCatalogObjectType::FUNCTION: { |
| 211 | // The key looks like: <db>.fn(<args>). We need to parse out the |