microo8 / plgo

easily create postgresql extensions in golang; moved to gitlab.com/microo8/plgo
292 stars 22 forks source link

INSERT cannot be used in non-volatile function #27

Closed AoAnima closed 5 years ago

AoAnima commented 5 years ago

Hello! Help me pls, when I try to insert or update, postgres gives an error ERROR: INSERT cannot be used in non-volatile function

Although it is indicated in the generated sql file that the volatility function CREATE OR REPLACE FUNCTION SaveData() RETURNS text AS '$libdir/main', 'SaveData' LANGUAGE c VOLATILE STRICT;

microo8 commented 5 years ago

Do you call some other function from SaveData? Or is there a trigger? This error occurs in a db.Query call?

AoAnima commented 5 years ago

Hello! Yes, I already figured out. added to

type Stmt struct {
    spiPlan C.SPIPlanPtr
    db      *DB
    typeIds []C.Oid
     readOnly bool
}

func (db *DB) Prepare(query string, types []string) (*Stmt, error) {
...
readOnly := true
    if !strings.HasPrefix(query,"SELECT") {
        readOnly=!strings.HasPrefix(query,"INSERT")
        if readOnly {
            readOnly=!strings.HasPrefix(query,"UPDATE")
        }
    }
...
return &Stmt{spiPlan: cplan, db: db, typeIds: typeIds, readOnly:readOnly}, nil
...
}

func (stmt *Stmt) Query(args ...interface{}) (*Rows, error) {
...
rv := C.SPI_execute_plan(stmt.spiPlan, valuesP, nullsP, (C._Bool)(stmt.readOnly), 0)
...
}