This is an automated email from the ASF dual-hosted git repository.

abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 05ead6880 fix: migration bugs on postgres (#5695)
05ead6880 is described below

commit 05ead688020ea1b9287ab8d130a747b686be82f3
Author: abeizn <[email protected]>
AuthorDate: Tue Jul 18 23:26:01 2023 +0800

    fix: migration bugs on postgres (#5695)
    
    * fix: migration bugs on postgres
---
 backend/helpers/migrationhelper/migrationhelper.go |  8 +++++++-
 backend/impls/dalgorm/dalgorm.go                   | 19 +++++++++++++++++++
 backend/impls/dalgorm/dalgorm_transaction.go       | 17 +++++++++--------
 3 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/backend/helpers/migrationhelper/migrationhelper.go 
b/backend/helpers/migrationhelper/migrationhelper.go
index 4de96c326..86cb341bf 100644
--- a/backend/helpers/migrationhelper/migrationhelper.go
+++ b/backend/helpers/migrationhelper/migrationhelper.go
@@ -263,13 +263,19 @@ func CopyTableColumns[S any, D any](
        if err != nil {
                return errors.Default.Wrap(err, fmt.Sprintf("failed to load 
data from src table [%s]", srcTableName))
        }
-       defer cursor.Close()
+       if !reflect.ValueOf(cursor).IsNil() {
+               defer cursor.Close()
+       }
+
        batch, err := helper.NewBatchSave(basicRes, reflect.TypeOf(new(D)), 
200, dstTableName)
        if err != nil {
                return errors.Default.Wrap(err, fmt.Sprintf("failed to 
instantiate BatchSave for table [%s]", srcTableName))
        }
        defer batch.Close()
 
+       if reflect.ValueOf(cursor).IsNil() {
+               return nil
+       }
        for cursor.Next() {
                srcTable := new(S)
                err1 := db.Fetch(cursor, srcTable)
diff --git a/backend/impls/dalgorm/dalgorm.go b/backend/impls/dalgorm/dalgorm.go
index 5acde4faa..1b5f5aa02 100644
--- a/backend/impls/dalgorm/dalgorm.go
+++ b/backend/impls/dalgorm/dalgorm.go
@@ -415,6 +415,18 @@ func (d *Dalgorm) IsDuplicationError(err error) bool {
        return strings.Contains(strings.ToLower(err.Error()), "duplicate")
 }
 
+// IsCachedPlanError checks if the error is related to postgres cached query 
plan
+// This error occurs occasionally in Postgres when reusing a cached query
+// plan. It can be safely ignored since it does not actually affect results.
+func (d *Dalgorm) IsCachedPlanError(err error) bool {
+       return strings.Contains(strings.ToLower(err.Error()), "cached plan must 
not change result type")
+}
+
+// IsJsonOrderError checks if the error is related to postgres json ordering
+func (d *Dalgorm) IsJsonOrderError(err error) bool {
+       return strings.Contains(err.Error(), "identify an ordering operator for 
type json")
+}
+
 // RawCursor (Deprecated) executes raw sql query and returns a database cursor
 func (d *Dalgorm) RawCursor(query string, params ...interface{}) (*sql.Rows, 
errors.Error) {
        rows, err := d.db.Raw(query, params...).Rows()
@@ -436,5 +448,12 @@ func (d *Dalgorm) convertGormError(err error) errors.Error 
{
        if d.IsDuplicationError(err) {
                return errors.BadInput.WrapRaw(err)
        }
+       if d.IsJsonOrderError(err) {
+               return errors.BadInput.WrapRaw(err)
+       }
+       if d.IsCachedPlanError(err) {
+               return nil
+       }
+
        panic(err)
 }
diff --git a/backend/impls/dalgorm/dalgorm_transaction.go 
b/backend/impls/dalgorm/dalgorm_transaction.go
index ed839e06a..9ba88c935 100644
--- a/backend/impls/dalgorm/dalgorm_transaction.go
+++ b/backend/impls/dalgorm/dalgorm_transaction.go
@@ -68,19 +68,20 @@ func (t *DalgormTransaction) LockTables(lockTables 
dal.LockTables) errors.Error
                }
                return t.Exec(fmt.Sprintf("LOCK TABLES %s", clause))
        case "postgres":
-               clause := ""
                for _, lockTable := range lockTables {
-                       if clause != "" {
-                               clause += ", "
-                       }
-                       clause += lockTable.TableName()
+                       var clause string
                        if lockTable.Exclusive {
-                               clause += "  IN EXCLUSIVE MODE"
+                               clause = "EXCLUSIVE"
                        } else {
-                               clause += "  IN SHARE MODE"
+                               clause = "SHARE"
+                       }
+                       stmt := fmt.Sprintf("LOCK TABLE %s IN %s MODE;", 
lockTable.TableName(), clause)
+                       err := t.Exec(stmt)
+                       if err != nil {
+                               return err
                        }
                }
-               return t.Exec(fmt.Sprintf("LOCK TABLE %s", clause))
+               return nil
        default:
                panic(fmt.Errorf("unknown dialect %s", t.Dialect()))
        }

Reply via email to