Source code: org/hsqldb/Trace.java
1 /* Copyrights and Licenses
2 *
3 * This product includes Hypersonic SQL.
4 * Originally developed by Thomas Mueller and the Hypersonic SQL Group.
5 *
6 * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 * - Redistributions of source code must retain the above copyright notice, this list of conditions
10 * and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright notice, this list of
12 * conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 * - All advertising materials mentioning features or use of this software must display the
15 * following acknowledgment: "This product includes Hypersonic SQL."
16 * - Products derived from this software may not be called "Hypersonic SQL" nor may
17 * "Hypersonic SQL" appear in their names without prior written permission of the
18 * Hypersonic SQL Group.
19 * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
20 * product includes Hypersonic SQL."
21 * This software is provided "as is" and any expressed or implied warranties, including, but
22 * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
23 * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
24 * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
25 * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
26 * or business interruption). However caused any on any theory of liability, whether in contract,
27 * strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this
28 * software, even if advised of the possibility of such damage.
29 * This software consists of voluntary contributions made by many individuals on behalf of the
30 * Hypersonic SQL Group.
31 *
32 *
33 * For work added by the HSQL Development Group:
34 *
35 * Copyright (c) 2001-2002, The HSQL Development Group
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions are met:
40 *
41 * Redistributions of source code must retain the above copyright notice, this
42 * list of conditions and the following disclaimer, including earlier
43 * license statements (above) and comply with all above license conditions.
44 *
45 * Redistributions in binary form must reproduce the above copyright notice,
46 * this list of conditions and the following disclaimer in the documentation
47 * and/or other materials provided with the distribution, including earlier
48 * license statements (above) and comply with all above license conditions.
49 *
50 * Neither the name of the HSQL Development Group nor the names of its
51 * contributors may be used to endorse or promote products derived from this
52 * software without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
58 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
59 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
60 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65 */
66
67
68 package org.hsqldb;
69
70 import java.sql.DriverManager;
71 import java.sql.SQLException;
72 import java.io.File;
73 import java.io.PrintWriter;
74
75 /**
76 * handles creation and reporting of error messages and throwing SQLException
77 *
78 * @version 1.7.0
79 */
80
81 // fredt@users 20020130 - patch 476694 by velichko@users - savepoints
82 // additions in different parts to support savepoint transactions
83 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - error reporting
84 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - setting trace
85 // the system property hsqldb.trace == true is now used for setting tracing on
86 // the system property hsqldb.tracesystemout == true is now used for printing
87 // trace message to System.out
88 // fredt@users 20020305 - patch 1.7.0 - various new messages added
89 // tony_lai@users 20020820 - patch 595073 by tlai@users Duplicated exception msg
90 public class Trace extends PrintWriter {
91
92 public static boolean TRACE = false;
93 public static boolean TRACESYSTEMOUT = false;
94 public static final boolean STOP = false;
95 public static final boolean DOASSERT = false;
96 private static Trace tTracer = new Trace();
97 private static String sTrace;
98 private static int iStop = 0;
99 public static final int DATABASE_ALREADY_IN_USE = 1,
100 CONNECTION_IS_CLOSED = 2,
101 CONNECTION_IS_BROKEN = 3,
102 DATABASE_IS_SHUTDOWN = 4,
103 COLUMN_COUNT_DOES_NOT_MATCH = 5,
104 DIVISION_BY_ZERO = 6,
105 INVALID_ESCAPE = 7,
106 INTEGRITY_CONSTRAINT_VIOLATION = 8,
107 VIOLATION_OF_UNIQUE_INDEX = 9,
108 TRY_TO_INSERT_NULL = 10,
109 UNEXPECTED_TOKEN = 11,
110 UNEXPECTED_END_OF_COMMAND = 12,
111 UNKNOWN_FUNCTION = 13,
112 NEED_AGGREGATE = 14,
113 SUM_OF_NON_NUMERIC = 15,
114 WRONG_DATA_TYPE = 16,
115 SINGLE_VALUE_EXPECTED = 17,
116 SERIALIZATION_FAILURE = 18,
117 TRANSFER_CORRUPTED = 19,
118 FUNCTION_NOT_SUPPORTED = 20,
119 TABLE_ALREADY_EXISTS = 21,
120 TABLE_NOT_FOUND = 22,
121 INDEX_ALREADY_EXISTS = 23,
122 SECOND_PRIMARY_KEY = 24,
123 DROP_PRIMARY_KEY = 25,
124 INDEX_NOT_FOUND = 26,
125 COLUMN_ALREADY_EXISTS = 27,
126 COLUMN_NOT_FOUND = 28,
127 FILE_IO_ERROR = 29,
128 WRONG_DATABASE_FILE_VERSION = 30,
129 DATABASE_IS_READONLY = 31,
130 DATA_IS_READONLY = 32,
131 ACCESS_IS_DENIED = 33,
132 INPUTSTREAM_ERROR = 34,
133 NO_DATA_IS_AVAILABLE = 35,
134 USER_ALREADY_EXISTS = 36,
135 USER_NOT_FOUND = 37,
136 ASSERT_FAILED = 38,
137 EXTERNAL_STOP = 39,
138 GENERAL_ERROR = 40,
139 WRONG_OUT_PARAMETER = 41,
140 ERROR_IN_FUNCTION = 42,
141 TRIGGER_NOT_FOUND = 43,
142 SAVEPOINT_NOT_FOUND = 44,
143 LABEL_REQUIRED = 45,
144 WRONG_DEFAULT_CLAUSE = 46,
145 FOREIGN_KEY_NOT_ALLOWED = 47,
146 UNKNOWN_DATA_SOURCE = 48,
147 BAD_INDEX_CONSTRAINT_NAME = 49,
148 DROP_FK_INDEX = 50,
149 RESULTSET_FORWARD_ONLY = 51,
150 VIEW_ALREADY_EXISTS = 52,
151 VIEW_NOT_FOUND = 53,
152 NOT_A_VIEW = 54,
153 NOT_A_TABLE = 55,
154 SYSTEM_INDEX = 56,
155 COLUMN_TYPE_MISMATCH = 57,
156 BAD_ADD_COLUMN_DEFINITION = 58,
157 DROP_SYSTEM_CONSTRAINT = 59,
158 CONSTRAINT_ALREADY_EXISTS = 60,
159 CONSTRAINT_NOT_FOUND = 61,
160 INVALID_JDBC_ARGUMENT = 62,
161 DATABASE_IS_MEMORY_ONLY = 63,
162 OUTER_JOIN_CONDITION = 64,
163 NUMERIC_VALUE_OUT_OF_RANGE = 65;
164 private static String[] sDescription = {
165 "NOT USED", "08001 The database is already in use by another process",
166 "08003 Connection is closed", "08003 Connection is broken",
167 "08003 The database is shutdown", "21000 Column count does not match",
168 "22012 Division by zero", "22019 Invalid escape character",
169 "23000 Integrity constraint violation",
170 "23000 Violation of unique index",
171 "23000 Try to insert null into a non-nullable column",
172 "37000 Unexpected token", "37000 Unexpected end of command",
173 "37000 Unknown function", "37000 Need aggregate function or group by",
174 "37000 Sum on non-numeric data not allowed", "37000 Wrong data type",
175 "37000 Single value expected", "40001 Serialization failure",
176 "40001 Transfer corrupted", "IM001 This function is not supported",
177 "S0001 Table already exists", "S0002 Table not found",
178 "S0011 Index already exists",
179 "S0011 Attempt to define a second primary key",
180 "S0011 Attempt to drop the primary key", "S0012 Index not found",
181 "S0021 Column already exists", "S0022 Column not found",
182 "S1000 File input/output error", "S1000 Wrong database file version",
183 "S1000 The database is in read only mode",
184 "S1000 The table data is read only", "S1000 Access is denied",
185 "S1000 InputStream error", "S1000 No data is available",
186 "S1000 User already exists", "S1000 User not found",
187 "S1000 Assert failed", "S1000 External stop request",
188 "S1000 General error", "S1009 Wrong OUT parameter",
189 "S1010 Error in function", "S0002 Trigger not found",
190 "S1011 Savepoint not found", "37000 Label required for value list",
191 "37000 Wrong data type or data too long in DEFAULT clause",
192 "S0011 Foreign key not allowed",
193 "S1000 The table's data source for this connection is not known",
194 "S0000 User-defined index or constraint name cannot begin with SYS_",
195 "S0011 Attempt to drop a foreign key index",
196 "S1000 ResultSet was set to forward only",
197 "S0003 View already exists", "S0004 View not found",
198 "S0005 Not A View", "S0005 Not A Table",
199 "S0011 Attempt to drop or rename a system index",
200 "S0021 Column types do not match",
201 "s0021 Column constraints are not acceptable",
202 "S0011 Attempt to drop a system constraint",
203 "S0011 Constraint already exists", "S0011 Constraint not found",
204 "SOO10 Invalid argument in JDBC call",
205 "S1000 Database is memory only",
206 "37000 only one join condition on table columns allowed",
207 "22003 Numeric value out of range"
208 };
209
210 static {
211 try {
212 TRACE = Boolean.getBoolean("hsqldb.trace");
213 TRACESYSTEMOUT = Boolean.getBoolean("hsqldb.tracesystemout");
214 } catch (Exception e) {}
215 }
216
217 /**
218 * Method declaration
219 *
220 *
221 * @param code
222 * @param add
223 *
224 * @return
225 */
226 static SQLException getError(int code, Object add) {
227
228 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
229 code = Math.abs(code);
230
231 String s = getMessage(code);
232
233 if (add != null) {
234 s += ": " + add.toString();
235 }
236
237 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
238 return new SQLException(s.substring(6), s.substring(0, 5), -code);
239
240 //return getError(s);
241 }
242
243 /**
244 * Creates a SQLException useing given message and code. The status is
245 * filled based on the code.
246 * <p>
247 * Note use the given msg as error message, not as "add" argument.
248 *
249 *
250 * @param msg
251 * @param code
252 *
253 * @return a SQLException created from the given message and code.
254 */
255
256 // tony_lai@users 20020820 - patch 595073
257 static SQLException getError(String msg, int code) {
258
259 code = Math.abs(code);
260
261 String s = getMessage(code);
262
263 return new SQLException(msg, s.substring(0, 5), -code);
264 }
265
266 /**
267 * Method declaration
268 *
269 *
270 * @param code
271 *
272 * @return
273 */
274 static String getMessage(int code) {
275 return sDescription[code];
276 }
277
278 /**
279 * Method declaration
280 *
281 *
282 * @param e
283 *
284 * @return
285 */
286 static String getMessage(SQLException e) {
287 return e.getSQLState() + " " + e.getMessage();
288 }
289
290 /**
291 * Method declaration
292 *
293 *
294 * @param msg
295 *
296 * @return
297 */
298 static SQLException getError(String msg) {
299 return new SQLException(msg.substring(6), msg.substring(0, 5),
300 -GENERAL_ERROR);
301 }
302
303 /**
304 * Method declaration
305 *
306 *
307 * @param code
308 *
309 * @return
310 */
311 public static SQLException error(int code) {
312 return getError(code, null);
313 }
314
315 /**
316 * Method declaration
317 *
318 *
319 * @param code
320 * @param s
321 *
322 * @return
323 */
324 public static SQLException error(int code, String s) {
325 return getError(code, s);
326 }
327
328 /**
329 * Method declaration
330 *
331 *
332 * @param code
333 * @param i
334 *
335 * @return
336 */
337 public static SQLException error(int code, int i) {
338 return getError(code, String.valueOf(i));
339 }
340
341 /**
342 * Method declaration
343 *
344 *
345 * @param condition
346 *
347 * @throws SQLException
348 */
349 static void doAssert(boolean condition) throws SQLException {
350 doAssert(condition, null);
351 }
352
353 /**
354 * Method declaration
355 *
356 *
357 * @param condition
358 * @param error
359 *
360 * @throws SQLException
361 */
362 static void doAssert(boolean condition,
363 String error) throws SQLException {
364
365 if (!condition) {
366 printStack();
367
368 throw getError(ASSERT_FAILED, error);
369 }
370 }
371
372 /**
373 * Method declaration
374 *
375 *
376 * @param condition
377 * @param code
378 *
379 * @throws SQLException
380 */
381 static void check(boolean condition, int code) throws SQLException {
382 check(condition, code, null);
383 }
384
385 /**
386 * Method declaration
387 *
388 *
389 * @param condition
390 * @param code
391 * @param s
392 *
393 * @throws SQLException
394 */
395 static void check(boolean condition, int code,
396 Object add) throws SQLException {
397
398 if (!condition) {
399 throw getError(code, add);
400 }
401 }
402
403 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
404 // for the PrinterWriter interface
405
406 /**
407 * Method declaration
408 *
409 *
410 * @param c
411 */
412 public void println(char c[]) {
413
414 String s = new String(c);
415
416 if (sTrace.equals("") && (s.indexOf("hsqldb.Trace") == -1)
417 && (s.indexOf("hsqldb") != -1)) {
418 int i = s.indexOf('.');
419
420 if (i != -1) {
421 s = s.substring(i + 1);
422 }
423
424 i = s.indexOf('(');
425
426 if (i != -1) {
427 s = s.substring(0, i);
428 }
429
430 sTrace = s;
431 }
432 }
433
434 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
435 public void println(String s) {
436
437 if (sTrace.equals("") && (s.indexOf("hsqldb.Trace") == -1)
438 && (s.indexOf("hsqldb") != -1)) {
439 int i = s.indexOf('.');
440
441 if (i != -1) {
442 s = s.substring(i + 1);
443 }
444
445 i = s.indexOf('(');
446
447 if (i != -1) {
448 s = s.substring(0, i);
449 }
450
451 sTrace = s;
452 }
453 }
454
455 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
456 public void write(String s) {
457 ;
458 }
459
460 /**
461 * Constructor declaration
462 *
463 */
464 Trace() {
465 super(System.out);
466 }
467
468 /**
469 * Used to print messages to System.out
470 *
471 *
472 * @param message message to print
473 */
474 static void printSystemOut(String message) {
475 System.out.println(message);
476 }
477
478 /**
479 * Method declaration
480 *
481 *
482 * @param l
483 */
484 static void trace(long l) {
485 traceCaller(String.valueOf(l));
486 }
487
488 /**
489 * Method declaration
490 *
491 *
492 * @param i
493 */
494 static void trace(int i) {
495 traceCaller(String.valueOf(i));
496 }
497
498 /**
499 * Method declaration
500 *
501 */
502 static void trace() {
503 traceCaller("");
504 }
505
506 /**
507 * Method declaration
508 *
509 *
510 * @param s
511 */
512 static void trace(String s) {
513 traceCaller(s);
514 }
515
516 /**
517 * Method declaration
518 *
519 *
520 * @throws SQLException
521 */
522 static void stop() throws SQLException {
523 stop(null);
524 }
525
526 /**
527 * Method declaration
528 *
529 *
530 * @param s
531 *
532 * @throws SQLException
533 */
534 static void stop(String s) throws SQLException {
535
536 if (iStop++ % 10000 != 0) {
537 return;
538 }
539
540 if (new File("trace.stop").exists()) {
541 printStack();
542
543 throw getError(EXTERNAL_STOP, s);
544 }
545 }
546
547 // fredt@users 20010701 - patch 418014 by deforest@users
548
549 /**
550 * With trace enabled, it is sometimes hard to figure out
551 * what a true exception is versus an exception generated
552 * by the tracing engine. These two methods define
553 * specialized versions Exceptions that are thrown during
554 * tracing so you can more easily differentiate between a
555 * Exception and a TraceException.
556 */
557 private static void printStack() {
558
559 class TraceException extends Exception {
560
561 TraceException() {
562 super("Trace");
563 }
564 }
565 ;
566
567 Exception e = new TraceException();
568
569 e.printStackTrace();
570 }
571
572 private static void traceCaller(String s) {
573
574 class TraceCallerException extends Exception {
575
576 TraceCallerException() {
577 super("TraceCaller");
578 }
579 }
580 ;
581
582 Exception e = new TraceCallerException();
583
584 sTrace = "";
585
586 e.printStackTrace(tTracer);
587
588 s = sTrace + "\t" + s;
589
590 // fredt@users 20010701 - patch 418014 by deforest@users
591 // trace to System.out is handy if only trace messages of hsql are required
592 if (TRACESYSTEMOUT) {
593 System.out.println(s);
594 } else {
595 DriverManager.println(s);
596 }
597 }
598 }