blob: 95a0a901b082178a3e027d43a028bc04e3211325 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package avatica
import (
"regexp"
"strconv"
"github.com/apache/calcite-avatica-go/message"
)
// Error severity codes
const (
Eunknown int8 = iota
Efatal
Eerror
Ewarning
)
// RPCMetadata contains metadata about the call that caused the error.
type RPCMetadata struct {
ServerAddress string
}
// ErrorCode represents the error code returned by the avatica server
type ErrorCode uint32
// SQLState represents the SQL code returned by the avatica server
type SQLState string
// ResponseError is an error type that contains detailed information on
// what caused the server to return an error.
type ResponseError struct {
Exceptions []string
HasExceptions bool
ErrorMessage string
Severity int8
ErrorCode ErrorCode
SqlState SQLState
Metadata *RPCMetadata
}
func (r ResponseError) Error() string {
msg := "An error was encountered while processing your request"
if r.ErrorMessage != "" {
msg += ": " + r.ErrorMessage
} else if len(r.Exceptions) > 0 {
msg += ":\n" + r.Exceptions[0]
}
return msg
}
// Name returns the name of the error encountered by the server.
func (r ResponseError) Name() string {
return errorCodeNames[r.ErrorCode]
}
// errorResponseToReponseError converts an error protocol buffer response
// to a native golang error.
func errorResponseToResponseError(message *message.ErrorResponse) ResponseError {
var (
errorCode int
sqlState string
)
re := regexp.MustCompile(`ERROR (\d+) \(([0-9a-zA-Z]+)\)`)
codes := re.FindStringSubmatch(message.ErrorMessage)
if len(codes) > 1 {
errorCode, _ = strconv.Atoi(codes[1])
}
if len(codes) > 2 {
sqlState = codes[2]
}
err := ResponseError{
Exceptions: message.Exceptions,
ErrorMessage: message.ErrorMessage,
Severity: int8(message.Severity),
ErrorCode: ErrorCode(errorCode),
SqlState: SQLState(sqlState),
Metadata: &RPCMetadata{
ServerAddress: message.GetMetadata().ServerAddress,
},
}
return err
}
var errorCodeNames = map[ErrorCode]string{
// Connection exceptions (errorcode 01, sqlstate 08)
101: "io_exception",
102: "malformed_connection_url",
103: "cannot_establish_connection",
// Data exceptions (errorcode 02, sqlstate 22)
201: "illegal_data",
202: "divide_by_zero",
203: "type_mismatch",
204: "value_in_upsert_not_constant",
205: "malformed_url",
206: "data_exceeds_max_capacity",
207: "missing_max_length",
208: "nonpositive_max_length",
209: "decimal_precision_out_of_range",
212: "server_arithmetic_error",
213: "value_outside_range",
214: "value_in_list_not_constant",
215: "single_row_subquery_returns_multiple_rows",
216: "subquery_returns_different_number_of_fields",
217: "ambiguous_join_condition",
218: "constraint_violation",
301: "concurrent_table_mutation",
302: "cannot_index_column_on_type",
// Invalid cursor state (errorcode 04, sqlstate 24)
401: "cursor_before_first_row",
402: "cursor_past_last_row",
// Syntax error or access rule violation (errorcode 05, sqlstate 42)
501: "ambiguous_table",
502: "ambiguous_column",
503: "index_missing_pk_columns",
504: "column_not_found",
505: "read_only_table",
506: "cannot_drop_pk",
509: "primary_key_missing",
510: "primary_key_already_exists",
511: "order_by_not_in_select_distinct",
512: "invalid_primary_key_constraint",
513: "array_not_allowed_in_primary_key",
514: "column_exist_in_def",
515: "order_by_array_not_supported",
516: "non_equality_array_comparison",
517: "invalid_not_null_constraint",
// Invalid transaction state (errorcode 05, sqlstate 25)
518: "read_only_connection",
519: "varbinary_array_not_supported",
// Expression index exceptions
520: "aggregate_expression_not_allowed_in_index",
521: "non_deterministic_expression_not_allowed_in_index",
522: "stateless_expression_not_allowed_in_index",
// Transaction exceptions
523: "transaction_conflict_exception",
524: "transaction_exception",
// Union all related errors
525: "select_column_num_in_unionall_diffs",
526: "select_column_type_in_unionall_diffs",
// Row timestamp column related errors
527: "rowtimestamp_one_pk_col_only",
528: "rowtimestamp_pk_col_only",
529: "rowtimestamp_create_only",
530: "rowtimestamp_col_invalid_type",
531: "rowtimestamp_not_allowed_on_view",
532: "invalid_scn",
// Column family related exceptions
1000: "single_pk_may_not_be_null",
1001: "column_family_not_found",
1002: "properties_for_family",
1003: "primary_key_with_family_name",
1004: "primary_key_out_of_order",
1005: "varbinary_in_row_key",
1006: "not_nullable_column_in_row_key",
1015: "varbinary_last_pk",
1023: "nullable_fixed_width_last_pk",
1036: "cannot_modify_view_pk",
1037: "base_table_column",
// Key/value column related errors
1007: "key_value_not_null",
// View related errors
1008: "view_with_table_config",
1009: "view_with_properties",
// Table related errors that are not in standard code
1010: "cannot_mutate_table",
1011: "unexpected_mutation_code",
1012: "table_undefined",
1013: "table_already_exist",
// Syntax error
1014: "type_not_supported_for_operator",
1016: "aggregate_in_group_by",
1017: "aggregate_in_where",
1018: "aggregate_with_not_group_by_column",
1019: "only_aggregate_in_having_clause",
1020: "upsert_column_numbers_mismatch",
// Table properties exception
1021: "invalid_bucket_num",
1022: "no_splits_on_salted_table",
1024: "salt_only_on_create_table",
1025: "set_unsupported_prop_on_alter_table",
1038: "cannot_add_not_nullable_column",
1026: "no_mutable_indexes",
1028: "invalid_index_state_transition",
1029: "invalid_mutable_index_config",
1030: "cannot_create_tenant_specific_table",
1034: "default_column_family_only_on_create_table",
1040: "insufficient_multi_tenant_columns",
1041: "tenantid_is_of_wrong_type",
1045: "view_where_is_constant",
1046: "cannot_update_view_column",
1047: "too_many_indexes",
1048: "no_local_index_on_table_with_immutable_rows",
1049: "column_family_not_allowed_table_property",
1050: "column_family_not_allowed_for_ttl",
1051: "cannot_alter_property",
1052: "cannot_set_property_for_column_not_added",
1053: "cannot_set_table_property_add_column",
1054: "no_local_indexes",
1055: "unallowed_local_indexes",
1056: "desc_varbinary_not_supported",
1057: "no_table_specified_for_wildcard_select",
1058: "unsupported_group_by_expressions",
1069: "default_column_family_on_shared_table",
1070: "only_table_may_be_declared_transactional",
1071: "tx_may_not_switch_to_non_tx",
1072: "store_nulls_must_be_true_for_transactional",
1073: "cannot_start_transaction_with_scn_set",
1074: "tx_max_versions_must_be_greater_than_one",
1075: "cannot_specify_scn_for_txn_table",
1076: "null_transaction_context",
1077: "transaction_failed",
1078: "cannot_create_txn_table_if_txns_disabled",
1079: "cannot_alter_to_be_txn_if_txns_disabled",
1080: "cannot_create_txn_table_with_row_timestamp",
1081: "cannot_alter_to_be_txn_with_row_timestamp",
1082: "tx_must_be_enabled_to_set_tx_context",
1083: "tx_must_be_enabled_to_set_auto_flush",
1084: "tx_must_be_enabled_to_set_isolation_level",
1085: "tx_unable_to_get_write_fence",
1086: "sequence_not_castable_to_auto_partition_id_column",
1087: "cannot_coerce_auto_partition_id",
// Sequence related
1200: "sequence_already_exist",
1201: "sequence_undefined",
1202: "start_with_must_be_constant",
1203: "increment_by_must_be_constant",
1204: "cache_must_be_non_negative_constant",
1205: "invalid_use_of_next_value_for",
1206: "cannot_call_current_before_next_value",
1207: "empty_sequence_cache",
1208: "minvalue_must_be_constant",
1209: "maxvalue_must_be_constant",
1210: "minvalue_must_be_less_than_or_equal_to_maxvalue",
1211: "starts_with_must_be_between_min_max_value",
1212: "sequence_val_reached_max_value",
1213: "sequence_val_reached_min_value",
1214: "increment_by_must_not_be_zero",
1215: "num_seq_to_allocate_must_be_constant",
1216: "num_seq_to_allocate_not_supported",
1217: "auto_partition_sequence_undefined",
// Parser error. (errorcode 06, sqlstate 42p)
601: "parser_error",
602: "missing_token",
603: "unwanted_token",
604: "mismatched_token",
605: "unknown_function",
// Implementation defined class. execution exceptions (errorcode 11, sqlstate xcl)
1101: "resultset_closed",
1102: "get_table_regions_fail",
1103: "execute_query_not_applicable",
1104: "execute_update_not_applicable",
1105: "split_point_not_constant",
1106: "batch_exception",
1107: "execute_update_with_non_empty_batch",
1108: "stale_region_boundary_cache",
1109: "cannot_split_local_index",
1110: "cannot_salt_local_index",
1120: "index_failure_block_write",
1130: "update_cache_frequency_invalid",
1131: "cannot_drop_col_append_only_schema",
1132: "view_append_only_schema",
// Implementation defined class. phoenix internal error. (errorcode 20, sqlstate int)
2001: "cannot_call_method_on_type",
2002: "class_not_unwrappable",
2003: "param_index_out_of_bound",
2004: "param_value_unbound",
2005: "interrupted_exception",
2006: "incompatible_client_server_jar",
2007: "outdated_jars",
2008: "index_metadata_not_found",
2009: "unknown_error_code",
6000: "operation_timed_out",
6001: "function_undefined",
6002: "function_already_exist",
6003: "unallowed_user_defined_functions",
721: "schema_already_exists",
722: "schema_not_found",
723: "cannot_mutate_schema",
}