1//  Copyright (c) 2014 Couchbase, Inc.
2//  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3//  except in compliance with the License. You may obtain a copy of the License at
4//    http://www.apache.org/licenses/LICENSE-2.0
5//  Unless required by applicable law or agreed to in writing, software distributed under the
6//  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
7//  either express or implied. See the License for the specific language governing permissions
8//  and limitations under the License.
9
10package errors
11
12import (
13	"fmt"
14
15	"github.com/couchbase/query/value"
16)
17
18// Execution errors - errors that are created in the execution package
19
20func NewExecutionPanicError(e error, msg string) Error {
21	return &err{level: EXCEPTION, ICode: 5001, IKey: "execution.panic", ICause: e,
22		InternalMsg: msg, InternalCaller: CallerN(1)}
23}
24
25func NewExecutionInternalError(what string) Error {
26	return &err{level: EXCEPTION, ICode: 5002, IKey: "execution.internal_error",
27		InternalMsg: fmt.Sprintf("Execution internal error: %v", what), InternalCaller: CallerN(1)}
28}
29
30func NewExecutionParameterError(what string) Error {
31	return &err{level: EXCEPTION, ICode: 5003, IKey: "execution.parameter_error",
32		InternalMsg: fmt.Sprintf("Execution parameter error: %v", what), InternalCaller: CallerN(1)}
33}
34
35func NewEvaluationError(e error, termType string) Error {
36	return &err{level: EXCEPTION, ICode: 5010, IKey: "execution.evaluation_error", ICause: e,
37		InternalMsg: fmt.Sprintf("Error evaluating %s.", termType), InternalCaller: CallerN(1)}
38}
39
40func NewExplainError(e error, msg string) Error {
41	return &err{level: EXCEPTION, ICode: 5015, IKey: "execution.explain_error", ICause: e,
42		InternalMsg: msg, InternalCaller: CallerN(1)}
43}
44
45func NewGroupUpdateError(e error, msg string) Error {
46	return &err{level: EXCEPTION, ICode: 5020, IKey: "execution.group_update_error", ICause: e,
47		InternalMsg: msg, InternalCaller: CallerN(1)}
48}
49
50func NewInvalidValueError(msg string) Error {
51	return &err{level: EXCEPTION, ICode: 5030, IKey: "execution.invalid_value_error",
52		InternalMsg: msg, InternalCaller: CallerN(1)}
53}
54
55func NewRangeError(termType string) Error {
56	return &err{level: EXCEPTION, ICode: 5035, IKey: "execution.range_error",
57		InternalMsg: fmt.Sprintf("Out of range evaluating %s.", termType), InternalCaller: CallerN(1)}
58}
59
60func NewDuplicateFinalGroupError() Error {
61	return &err{level: EXCEPTION, ICode: 5040, IKey: "execution.duplicate_final_group",
62		InternalMsg: "Duplicate Final Group.", InternalCaller: CallerN(1)}
63}
64
65func NewInsertKeyError(v value.Value) Error {
66	return &err{level: EXCEPTION, ICode: 5050, IKey: "execution.insert_key_error",
67		InternalMsg: fmt.Sprintf("No INSERT key for %v", v), InternalCaller: CallerN(1)}
68}
69
70func NewInsertValueError(v value.Value) Error {
71	return &err{level: EXCEPTION, ICode: 5060, IKey: "execution.insert_value_error",
72		InternalMsg: fmt.Sprintf("No INSERT value for %v", v), InternalCaller: CallerN(1)}
73}
74
75func NewInsertKeyTypeError(v value.Value) Error {
76	return &err{level: EXCEPTION, ICode: 5070, IKey: "execution.insert_key_type_error",
77		InternalMsg:    fmt.Sprintf("Cannot INSERT non-string key %v of type %T.", v, v),
78		InternalCaller: CallerN(1)}
79}
80
81func NewInsertOptionsTypeError(v value.Value) Error {
82	return &err{level: EXCEPTION, ICode: 5071, IKey: "execution.insert_options_type_error",
83		InternalMsg:    fmt.Sprintf("Cannot INSERT non-OBJECT options %v of type %T.", v, v),
84		InternalCaller: CallerN(1)}
85}
86
87func NewUpsertKeyError(v value.Value) Error {
88	return &err{level: EXCEPTION, ICode: 5072, IKey: "execution.upsert_key_error",
89		InternalMsg: fmt.Sprintf("No UPSERT key for %v", v), InternalCaller: CallerN(1)}
90}
91
92func NewUpsertValueError(v value.Value) Error {
93	return &err{level: EXCEPTION, ICode: 5075, IKey: "execution.upsert_value_error",
94		InternalMsg: fmt.Sprintf("No UPSERT value for %v", v), InternalCaller: CallerN(1)}
95}
96
97func NewUpsertKeyTypeError(v value.Value) Error {
98	return &err{level: EXCEPTION, ICode: 5078, IKey: "execution.upsert_key_type_error",
99		InternalMsg:    fmt.Sprintf("Cannot UPSERT non-string key %v of type %T.", v, v),
100		InternalCaller: CallerN(1)}
101}
102
103func NewUpsertOptionsTypeError(v value.Value) Error {
104	return &err{level: EXCEPTION, ICode: 5079, IKey: "execution.upsert_options_type_error",
105		InternalMsg:    fmt.Sprintf("Cannot UPSERT non-OBJECT options %v of type %T.", v, v),
106		InternalCaller: CallerN(1)}
107}
108
109func NewDeleteAliasMissingError(alias string) Error {
110	return &err{level: EXCEPTION, ICode: 5080, IKey: "execution.missing_delete_alias",
111		InternalMsg:    fmt.Sprintf("DELETE alias %s not found in item.", alias),
112		InternalCaller: CallerN(1)}
113}
114
115func NewDeleteAliasMetadataError(alias string) Error {
116	return &err{level: EXCEPTION, ICode: 5090, IKey: "execution.delete_alias_metadata",
117		InternalMsg:    fmt.Sprintf("DELETE alias %s has no metadata in item.", alias),
118		InternalCaller: CallerN(1)}
119}
120
121func NewUpdateAliasMissingError(alias string) Error {
122	return &err{level: EXCEPTION, ICode: 5100, IKey: "execution.missing_update_alias",
123		InternalMsg:    fmt.Sprintf("UPDATE alias %s not found in item.", alias),
124		InternalCaller: CallerN(1)}
125}
126
127func NewUpdateAliasMetadataError(alias string) Error {
128	return &err{level: EXCEPTION, ICode: 5110, IKey: "execution.update_alias_metadata",
129		InternalMsg:    fmt.Sprintf("UPDATE alias %s has no metadata in item.", alias),
130		InternalCaller: CallerN(1)}
131}
132
133func NewUpdateMissingClone() Error {
134	return &err{level: EXCEPTION, ICode: 5120, IKey: "execution.update_missing_clone",
135		InternalMsg: "Missing UPDATE clone.", InternalCaller: CallerN(1)}
136}
137
138func NewUnnestInvalidPosition(pos interface{}) Error {
139	return &err{level: EXCEPTION, ICode: 5180, IKey: "execution.unnest_invalid_position",
140		InternalMsg: fmt.Sprintf("Invalid UNNEST position of type %T.", pos), InternalCaller: CallerN(1)}
141}
142
143func NewScanVectorTooManyScannedBuckets(buckets []string) Error {
144	return &err{level: EXCEPTION, ICode: 5190, IKey: "execution.scan_vector_too_many_scanned_vectors",
145		InternalMsg: fmt.Sprintf("The scan_vector parameter should not be used for queries accessing more than one keyspace. "+
146			"Use scan_vectors instead. Keyspaces: %v", buckets), InternalCaller: CallerN(1)}
147}
148
149// Error code 5200 is retired. Do not reuse.
150
151func NewUserNotFoundError(u string) Error {
152	return &err{level: EXCEPTION, ICode: 5210, IKey: "execution.user_not_found",
153		InternalMsg: fmt.Sprintf("Unable to find user %s.", u), InternalCaller: CallerN(1)}
154}
155
156func NewRoleRequiresKeyspaceError(role string) Error {
157	return &err{level: EXCEPTION, ICode: 5220, IKey: "execution.role_requires_keyspace",
158		InternalMsg: fmt.Sprintf("Role %s requires a keyspace.", role), InternalCaller: CallerN(1)}
159}
160
161func NewRoleTakesNoKeyspaceError(role string) Error {
162	return &err{level: EXCEPTION, ICode: 5230, IKey: "execution.role_takes_no_keyspace",
163		InternalMsg: fmt.Sprintf("Role %s does not take a keyspace.", role), InternalCaller: CallerN(1)}
164}
165
166func NewNoSuchKeyspaceError(bucket string) Error {
167	return &err{level: EXCEPTION, ICode: 5240, IKey: "execution.no_such_keyspace",
168		InternalMsg: fmt.Sprintf("Keyspace %s is not valid.", bucket), InternalCaller: CallerN(1)}
169}
170
171func NewRoleNotFoundError(role string) Error {
172	return &err{level: EXCEPTION, ICode: 5250, IKey: "execution.role_not_found",
173		InternalMsg: fmt.Sprintf("Role %s is not valid.", role), InternalCaller: CallerN(1)}
174}
175
176func NewRoleAlreadyPresent(user string, role string, bucket string) Error {
177	var msg string
178	if bucket == "" {
179		msg = fmt.Sprintf("User %s already has role %s.", user, role)
180	} else {
181		msg = fmt.Sprintf("User %s already has role %s(%s).", user, role, bucket)
182	}
183	return &err{level: WARNING, ICode: 5260, IKey: "execution.role_already_present",
184		InternalMsg: msg, InternalCaller: CallerN(1)}
185}
186
187func NewRoleNotPresent(user string, role string, bucket string) Error {
188	var msg string
189	if bucket == "" {
190		msg = fmt.Sprintf("User %s did not have role %s.", user, role)
191	} else {
192		msg = fmt.Sprintf("User %s did not have role %s(%s).", user, role, bucket)
193	}
194	return &err{level: WARNING, ICode: 5270, IKey: "execution.role_not_present",
195		InternalMsg: msg, InternalCaller: CallerN(1)}
196}
197
198func NewUserWithNoRoles(user string) Error {
199	return &err{level: WARNING, ICode: 5280, IKey: "execution.user_with_no_roles",
200		InternalMsg:    fmt.Sprintf("User %s has no roles. Connecting with this user may not be possible", user),
201		InternalCaller: CallerN(1)}
202}
203
204// Error code 5290 is retired. Do not reuse.
205
206func NewHashTablePutError(e error) Error {
207	return &err{level: EXCEPTION, ICode: 5300, IKey: "execution.hash_table_put_error", ICause: e,
208		InternalMsg:    fmt.Sprintf("Hash Table Put failed"),
209		InternalCaller: CallerN(1)}
210}
211
212func NewHashTableGetError(e error) Error {
213	return &err{level: EXCEPTION, ICode: 5310, IKey: "execution.hash_table_get_error", ICause: e,
214		InternalMsg:    fmt.Sprintf("Hash Table Get failed"),
215		InternalCaller: CallerN(1)}
216}
217
218func NewMergeMultiUpdateError(key string) Error {
219	return &err{level: EXCEPTION, ICode: 5320, IKey: "execution.merge_multiple_update",
220		InternalMsg:    fmt.Sprintf("Multiple UPDATE/DELETE of the same document (document key '%s') in a MERGE statement", key),
221		InternalCaller: CallerN(1)}
222}
223
224func NewMergeMultiInsertError(key string) Error {
225	return &err{level: EXCEPTION, ICode: 5330, IKey: "execution.merge_multiple_insert",
226		InternalMsg:    fmt.Sprintf("Multiple INSERT of the same document (document key '%s') in a MERGE statement", key),
227		InternalCaller: CallerN(1)}
228}
229
230func NewWindowEvaluationError(e error, msg string) Error {
231	return &err{level: EXCEPTION, ICode: 5340, IKey: "execution.window_aggregate_error", ICause: e,
232		InternalMsg: msg, InternalCaller: CallerN(1)}
233}
234
235func NewAdviseIndexError(e error, msg string) Error {
236	return &err{level: EXCEPTION, ICode: 5350, IKey: "execution.advise_index_error", ICause: e,
237		InternalMsg: msg, InternalCaller: CallerN(1)}
238}
239
240func NewUpdateStatisticsError(msg string) Error {
241	return &err{level: EXCEPTION, ICode: 5360, IKey: "execution.update_statistics",
242		InternalMsg:    msg,
243		InternalCaller: CallerN(1)}
244}
245
246const SUBQUERY_BUILD = 5370
247
248func NewSubqueryBuildError(e error) Error {
249	return &err{level: EXCEPTION, ICode: SUBQUERY_BUILD, IKey: "execution.subquery.build", ICause: e,
250		InternalMsg:    "Unable to run subquery",
251		InternalCaller: CallerN(1)}
252}
253