Index: error-handling/src/odbc/error-base.lisp
===================================================================
--- error-handling/src/odbc/error-base.lisp	(revision error-handling,5)
+++ error-handling/src/odbc/error-base.lisp	(revision error-handling,5)
@@ -0,0 +1,47 @@
+(in-package :plain-odbc)
+
+
+
+;;; Basics of ODBC-ERRORs
+
+(defgeneric print-odbc-error (condition stream))
+
+(define-condition odbc-error (error)
+  ((message :initarg :message :reader error-message)
+   (code :initarg :code :reader error-code))
+  (:report print-odbc-error))
+
+(defmethod print-odbc-error (condition stream)
+  (with-slots (message code) condition
+    (format stream "[ODBC error] ~a; state: ~a" message code)))
+
+
+
+;;; Extended error definitions
+
+(defvar *errors-by-codes* (make-hash-table :test 'equal))
+
+(defmacro define-odbc-error (code class)
+  `(progn
+     (define-condition ,class (odbc-error) ())
+     (export ',class)
+     (setf (gethash ,code *errors-by-codes*) ',class)))
+
+(defmacro define-odbc-errors (&body defs)
+  `(progn
+     ,@(mapcar (lambda (def)
+                 (destructuring-bind (code class) def
+                   `(define-odbc-error ,code ,class)))
+               defs)))
+
+
+
+;;; Error selection and signalling
+
+(defun read-and-throw-error (henv hdbc hstmt)
+  (multiple-value-bind (error-message sql-state)
+      (handle-error (or henv (cffi:null-pointer))
+                    (or hdbc (cffi:null-pointer))
+                    (or hstmt (cffi:null-pointer)))
+    (let ((type (gethash sql-state *errors-by-codes* 'odbc-error)))
+      (error type :message error-message :code sql-state))))
Index: error-handling/src/odbc/error-defs.lisp
===================================================================
--- error-handling/src/odbc/error-defs.lisp	(revision error-handling,5)
+++ error-handling/src/odbc/error-defs.lisp	(revision error-handling,5)
@@ -0,0 +1,48 @@
+(in-package :plain-odbc)
+
+
+
+(define-odbc-errors
+  ("23502" odbc-not-null-violation)
+  ("23503" odbc-foreign-key-violation)
+  ("23505" odbc-unique-violation)
+  ("23514" odbc-check-violation)
+  ("42000" odbc-syntax-error-or-access-rule-violation)
+  ("42601" odbc-syntax-error)
+  ("42501" odbc-insufficient-privilege)
+  ("42846" odbc-cannot-coerce)
+  ("42803" odbc-grouping-error)
+  ("42830" odbc-invalid-foreign-key)
+  ("42602" odbc-invalid-name)
+  ("42622" odbc-name-too-long)
+  ("42939" odbc-reserved-name)
+  ("42804" odbc-datatype-mismatch)
+  ("42P18" odbc-indeterminate-datatype)
+  ("42809" odbc-wrong-object-type)
+  ("42703" odbc-undefined-column)
+  ("42883" odbc-undefined-function)
+  ("42P01" odbc-undefined-table)
+  ("42P02" odbc-undefined-parameter)
+  ("42704" odbc-undefined-object)
+  ("42701" odbc-duplicate-column)
+  ("42P03" odbc-duplicate-cursor)
+  ("42P04" odbc-duplicate-database)
+  ("42723" odbc-duplicate-function)
+  ("42P05" odbc-duplicate-prepared-statement)
+  ("42P06" odbc-duplicate-schema)
+  ("42P07" odbc-duplicate-table)
+  ("42712" odbc-duplicate-alias)
+  ("42710" odbc-duplicate-object)
+  ("42702" odbc-ambiguous-column)
+  ("42725" odbc-ambiguous-function)
+  ("42P08" odbc-ambiguous-parameter)
+  ("42P09" odbc-ambiguous-alias)
+  ("42P10" odbc-invalid-column-reference)
+  ("42611" odbc-invalid-column-definition)
+  ("42P11" odbc-invalid-cursor-definition)
+  ("42P12" odbc-invalid-database-definition)
+  ("42P13" odbc-invalid-function-definition)
+  ("42P14" odbc-invalid-prepared-statement-definition)
+  ("42P15" odbc-invalid-schema-definition)
+  ("42P16" odbc-invalid-table-definition)
+  ("42P17" odbc-invalid-object-definition))
Index: error-handling/plain-odbc.asd
===================================================================
--- error-handling/plain-odbc.asd	(revision error-handling,1)
+++ error-handling/plain-odbc.asd	(revision error-handling,5)
@@ -11,4 +11,6 @@
                          (:file "cffi-support")
                          (:file "odbc-ff-interface")
+                         (:file "error-base")
+                         (:file "error-defs")
                          (:file "odbc-functions")
                          (:file "parameter")
Index: error-handling/src/odbc/odbc-functions.lisp
===================================================================
--- error-handling/src/odbc/odbc-functions.lisp	(revision error-handling,4)
+++ error-handling/src/odbc/odbc-functions.lisp	(revision error-handling,5)
@@ -111,40 +111,4 @@
 
 
-(defun print-odbc-error (condition stream)
-  (with-slots (message code) condition
-    (format stream "[ODBC error] ~a; state: ~a" message code)))
-
-(define-condition odbc-error (error)
-  ((message :initarg :message :reader error-message)
-   (code :initarg :code :reader error-code))
-  (:report print-odbc-error))
-
-(define-condition odbc-not-null-violation (odbc-error) ())
-
-(define-condition odbc-foreign-key-error (odbc-error) ())
-
-(define-condition odbc-unique-violation (odbc-error) ())
-
-(define-condition odbc-check-violation (odbc-error) ())
-
-(define-condition odbc-insufficient-privilege (odbc-error) ())
-
-(define-condition odbc-undefined-object (odbc-error) ())
-
-(defun read-and-throw-error (henv hdbc hstmt)
-  (multiple-value-bind (error-message sql-state)
-      (handle-error (or henv (cffi:null-pointer))
-                    (or hdbc (cffi:null-pointer))
-                    (or hstmt (cffi:null-pointer)))
-    (let ((type (cdr (assoc sql-state '(("23502" . odbc-not-null-violation)
-                                        ("23503" . odbc-foreign-key-error)
-                                        ("23505" . odbc-unique-violation)
-                                        ("23514" . odbc-check-violation)
-                                        ("42501" . odbc-insufficient-privilege)
-                                        ("42704" . odbc-undefined-object))
-                            :test #'string=))))
-      (error (if type type 'odbc-error)
-             :message error-message
-             :code sql-state))))
 
 ;;; rav:
Index: error-handling/src/odbc/plain-odbc-package.lisp
===================================================================
--- error-handling/src/odbc/plain-odbc-package.lisp	(revision error-handling,4)
+++ error-handling/src/odbc/plain-odbc-package.lisp	(revision error-handling,5)
@@ -12,13 +12,8 @@
    "COMMON-LISP" #+mcl "CCL" #+cormanlisp "WIN32" "CFFI")
   (:export
+   "PRINT-ODBC-ERROR"
    "ODBC-ERROR"
    "ERROR-MESSAGE"
    "ERROR-CODE"
-   "ODBC-NOT-NULL-VIOLATION"
-   "ODBC-FOREIGN-KEY-VIOLATION"
-   "ODBC-UNIQUE-VIOLATION"
-   "ODBC-CHECK-VIOLATION"
-   "ODBC-INSUFFICIENT-PRIVILEGE"
-   "ODBC-UNDEFINED-OBJECT"
 
    "EXEC-QUERY" 
