catalogErrorCode narrows a "Catalog Error: …" message to a specific SQLSTATE
(msg string)
| 159 | return "0A000" // feature_not_supported |
| 160 | case strings.HasPrefix(msg, "Transaction Error:"), |
| 161 | strings.HasPrefix(msg, "TransactionContext Error:"): |
| 162 | return "25000" // invalid_transaction_state — DuckDB emits both prefixes |
| 163 | case strings.HasPrefix(msg, "Dependency Error:"): |
| 164 | return "2BP01" // dependent_objects_still_exist |
| 165 | } |
| 166 | // Unknown error class — no DuckDB prefix matched. These are |
| 167 | // typically infra issues (gRPC failures, IO errors, internal panics) |
| 168 | // rather than user input issues. Classify as XX000 (internal_error) |
| 169 | // so isUserQueryError correctly routes them to the system-error log |
| 170 | // path. If a future DuckDB error needs to land in a user class, add |
| 171 | // a prefix branch above instead of moving the fallback. |
| 172 | return "XX000" |
| 173 | } |
| 174 | |
| 175 | // transformErrorSQLState returns the SQLSTATE for a transpiler-detected error. |
| 176 | // A transform may attach an explicit code (e.g. 0A000 for an unsupported |
| 177 | // feature via transform.CodedError); otherwise it defaults to 42704 |
| 178 | // (undefined_object), matching the historical behavior for unrecognized config |
| 179 | // parameters. |
| 180 | func transformErrorSQLState(err error) string { |
| 181 | var coded interface{ SQLState() string } |
| 182 | if errors.As(err, &coded) { |
| 183 | return coded.SQLState() |
| 184 | } |
| 185 | return "42704" |
| 186 | } |
| 187 | |
| 188 | // unwrapFlightError recovers the underlying error message from an Arrow Flight / |
| 189 | // gRPC wrapper. gRPC errors stringify as "… rpc error: code = X desc = <message>", |
| 190 | // and the control plane further prefixes worker failures with "flight execute |
| 191 | // update: " (and similar). When the message is not Flight-wrapped it is returned |