Lisp HUG Maillist Archive

SQL and inheritance

Hi all,

When I inherit subclasses of classes which are themselves children of
sql:standard-db-object, I seem to have problems accessing the slots inheriting
from the base class, particularly if the base class slots are strings.  

I have included two simple test programs, and a session interactions in which
the code is invoked, to demonstrate this issue.  The first test shows unexpected
output, and the second test fails outright.  The second case is particularly
important, since the empty middle class is used within the rule structure.

I'm just wondering if I'm doing anything obviously wrong or unsupported. 

Thanks,
John

--- BEGIN PROGRAM LISTING ---

(load-all-patches)

(in-package "KW-USER") 

(require "kw")
(require "kw-sql")
(require "odbc")
(setf sql:*default-database-type* :odbc)
(sql:initialize-database-type)

(sql:def-view-class classa (sql:standard-db-object standard-kb-object)  
  ((slota :db-kind :key :type (string 20) :initarg :slot-a)))

(sql:def-view-class classb (classa)  
  ((slotb :db-kind :base :type integer :initarg :slot-b)))

(defun runTest ()
  (let ((database (sql:connect "PostgreSQL/postgres/notMyPass" :if-exists :old))
        (instance (make-instance 'classb :slot-a "stringtest" :slot-b 2)))
    (progn
      (sql:create-view-from-class 'classa)
      (sql:create-view-from-class 'classb)
      (sql:update-records-from-instance instance)  
      #.(sql:locally-enable-sql-reader-syntax)
      (let ((queriedResult (caar (sql:select 'classb))))
        (format t "getRgKBStructureByRGName() says slota =  ~A ~%" (slot-value
queriedResult 'slota)) 
        #.(sql:restore-sql-reader-syntax-state)
        (sql:drop-view-from-class 'classb)
        (sql:drop-view-from-class 'classa)))))

--- END PROGRAM LISTING ---

--- BEGIN SESSION INTERACTION ---

==> (load "c:\\lisp\\bugtest.lisp")
; Loading text file c:\lisp\bugtest.lisp
;  Loading text file C:\Program
Files\LispWorks\lib\4-4-0-0\private-patches\load.lisp
#P"c:/lisp/bugtest.lisp"

==> (runtest)
getRgKBStructureByRGName() says slota =  2005-07-01 00:00:00  
NIL

--- END SESSION INTERACTION ---

--- BEGIN PROGRAM LISTING ---

(load-all-patches)

(in-package "KW-USER") 

(require "kw")
(require "kw-sql")
(require "odbc")
(setf sql:*default-database-type* :odbc)
(sql:initialize-database-type)

(sql:def-view-class classa (sql:standard-db-object standard-kb-object)  
  ((slota :db-kind :key :type (string 20) :initarg :slot-a)))

(sql:def-view-class classb (classa)  
  ())

(sql:def-view-class classc (classb)
  ((slotc :db-kind :base :type integer :initarg :slot-c)))


(defun runTest ()
  (let ((database (sql:connect "PostgreSQL/postgres/notMyPassword" :if-exists :old))
        (instance (make-instance 'classc :slot-a "stringtest" :slot-c 2)))
    (progn
      (sql:create-view-from-class 'classa)
      (sql:create-view-from-class 'classb)
      (sql:create-view-from-class 'classc)
      (sql:update-records-from-instance instance)  
      #.(sql:locally-enable-sql-reader-syntax)
      (let ((queriedResult (caar (sql:select 'classc))))
        (format t "getRgKBStructureByRGName() says slota =  ~A ~%" (slot-value
queriedResult 'slota)) 
        #.(sql:restore-sql-reader-syntax-state)
        (sql:drop-view-from-class 'classc)
        (sql:drop-view-from-class 'classb)
        (sql:drop-view-from-class 'classa)))))

--- END PROGRAM LISTING ---

--- BEGIN SESSION INTERACTION ---

==> (load "C:\\lisp\\bugtest.lisp")
; Loading text file C:\lisp\bugtest.lisp
;  Loading text file C:\Program
Files\LispWorks\lib\4-4-0-0\private-patches\load.lisp
#P"C:/lisp/bugtest.lisp"

==> (runtest)

Error: Sql-Database-Data-Error id HY000[7] : ERROR:  relation "c4_classb" does
not exist
  1 (abort) Return to level 0.
  2 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other options



--- END SESSION INTERACTION --- 


Re: SQL and inheritance

I've figured this out.  Two points:

1)  Inheritance is not supported for those classes which inherit from
sql:standard-db-object.  Instead, inherit the kb classes separately, and enforce
types via accessor methods.

2)  Accessing string types in postgresql using the :odbc flag fails silently due
to different character classes being used for creation and use.  Instead, use
the :postgresql flag.  The format for the parameter to be passed to the flag is
(since I could not find this anywhere and guessed correctly based on the errors) 
"host=yourhost port=5432 dbname=YourDBName user=postgres password=yourPassword" 


Updated at: 2020-12-10 08:52 UTC