Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create and use [][]String types in postgres #219

Open
jacksoncalvert opened this issue Jul 31, 2024 · 0 comments
Open

Unable to create and use [][]String types in postgres #219

jacksoncalvert opened this issue Jul 31, 2024 · 0 comments

Comments

@jacksoncalvert
Copy link

jacksoncalvert commented Jul 31, 2024

Im using Gorm for the mapping gorm structs to database tables, and im trying to configure an easy way to do [][]string (text[][]) in postgres.

What im finding is the script created to insert data is correct, but the data that is passing through is being flattened into a []string array.

the code that ive found thats doing this is

func (plan *encodePlanDriverValuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
	dv := value.(driver.Valuer)
	if dv == nil {
		return nil, nil
	}
	v, err := dv.Value()
	if err != nil {
		return nil, err
	}
	if v == nil {
		return nil, nil
	}

	newBuf, err = plan.m.Encode(plan.oid, plan.formatCode, v, buf)
	if err == nil {
		return newBuf, nil
	}

	s, ok := v.(string)
	if !ok {
		return nil, err
	}

	var scannedValue any
	scanErr := plan.m.Scan(plan.oid, TextFormatCode, []byte(s), &scannedValue)
	if scanErr != nil {
		return nil, err
	}

	// Prevent infinite loop. We can't encode this. See https://github.com/jackc/pgx/issues/1331.
	if reflect.TypeOf(value) == reflect.TypeOf(scannedValue) {
		return nil, fmt.Errorf("tried to encode %v via encoding to text and scanning but failed due to receiving same type back", value)
	}

	var err2 error
	newBuf, err2 = plan.m.Encode(plan.oid, BinaryFormatCode, scannedValue, buf)
	if err2 != nil {
		return nil, err
	}

	return newBuf, nil
}

and im working through a struct thats similar to this

import "github.com/lib/pq"

type Task struct {
	ID             string      `json:"id" gorm:"primaryKey;column:id;"`
	TaskName       *string     `json:"taskName" gorm:"column:taskName"`
	Liststringtask pq.GenericArray `json:"liststringtask" gorm:"column:liststringtask;type:text[][]"`
}

Ive found so far that this line is pushing a correctly formatted 2d string array into a 1d string array, and if i change it from

var scannedValue any
	scanErr := plan.m.Scan(plan.oid, TextFormatCode, []byte(s), &scannedValue)
	if scanErr != nil {
		return nil, err
	}

to

var scannedValue [][]string
	scanErr := plan.m.Scan(plan.oid, TextFormatCode, []byte(s), &scannedValue)
	if scanErr != nil {
		return nil, err
	}

then the insertion into the db is correct and then scannedValue is of the correct type. Is there another way to create 2d (or multi-d) arrays for postgres?

@jacksoncalvert jacksoncalvert changed the title Unable to create and user [][]String types in postgres Unable to create and use [][]String types in postgres Jul 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant