Skip to content

feat: support the RowsColumnType interface#800

Draft
olavloite wants to merge 1 commit intomainfrom
rows-column-type
Draft

feat: support the RowsColumnType interface#800
olavloite wants to merge 1 commit intomainfrom
rows-column-type

Conversation

@olavloite
Copy link
Copy Markdown
Collaborator

No description provided.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements several optional database/sql/driver interfaces for the rows struct, providing metadata about column types such as scan types, database type names, and precision/scale. The implementation includes support for both GoogleSQL and PostgreSQL dialects. Review feedback highlights an inconsistency in DATE and UUID array decoding compared to scalar types and suggests returning []any instead of any for unknown array elements. Additionally, it is recommended to use standard PostgreSQL array syntax (e.g., text[]) rather than internal names (e.g., _int8) for better consistency and user familiarity.

Comment thread rows.go
Comment on lines +604 to +607
et := scanType(t.ArrayElementType, decodeToNativeArrays, state)
if decodeToNativeArrays {
return reflect.SliceOf(et)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There is an inconsistency in how DATE and UUID types are handled between scalar and array decoding when decodeToNativeArrays is true. Scalar DATE and UUID values are decoded as string (see lines 323 and 352), but their array counterparts are decoded as []civil.Date and []uuid.UUID (see lines 464 and 498). The current implementation of scanType would incorrectly return []string for these arrays because it recursively calls scanType on the element type.

		et := scanType(t.ArrayElementType, decodeToNativeArrays, state)
		if decodeToNativeArrays {
			switch t.ArrayElementType.Code {
			case sppb.TypeCode_DATE:
				return reflect.TypeOf([]civil.Date{})
			case sppb.TypeCode_UUID:
				return reflect.TypeOf([]uuid.UUID{})
			}
			return reflect.SliceOf(et)
		}

Comment thread rows.go
Comment on lines +601 to +603
if t.ArrayElementType == nil {
return reflect.TypeOf([]any{}).Elem()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When the array element type is unknown, ColumnTypeScanType should return a slice type (e.g., []any) rather than the element type any. reflect.TypeOf([]any{}).Elem() evaluates to interface{}, which represents a scalar value.

Suggested change
if t.ArrayElementType == nil {
return reflect.TypeOf([]any{}).Elem()
}
if t.ArrayElementType == nil {
return reflect.TypeOf([]any{})
}

Comment thread rows.go
Comment on lines +716 to +739
if isPG {
switch t.ArrayElementType.Code {
case sppb.TypeCode_STRING:
return "_text"
case sppb.TypeCode_INT64:
return "_int8"
case sppb.TypeCode_FLOAT64:
return "_float8"
case sppb.TypeCode_BOOL:
return "_bool"
case sppb.TypeCode_BYTES:
return "_bytea"
case sppb.TypeCode_DATE:
return "_date"
case sppb.TypeCode_TIMESTAMP:
return "_timestamptz"
case sppb.TypeCode_NUMERIC:
return "_numeric"
case sppb.TypeCode_JSON:
return "_jsonb"
default:
return "_" + databaseTypeName(t.ArrayElementType, dialect)
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The database type names for PostgreSQL arrays are inconsistent with the scalar type names and use internal PostgreSQL names (e.g., _int8 for bigint[]). It is better to use the standard typename[] syntax, which is consistent with the scalar names returned by this function and more familiar to users. This also simplifies the implementation by removing the need for a separate switch statement for PG arrays.

		if isPG {
			return databaseTypeName(t.ArrayElementType, dialect) + "[]"
		}

Comment thread rows_test.go
if g, w := rpg.ColumnTypeDatabaseTypeName(2), "numeric"; g != w {
t.Errorf("ColumnTypeDatabaseTypeName(2) PG mismatch\n Got: %v\nWant: %v", g, w)
}
if g, w := rpg.ColumnTypeDatabaseTypeName(3), "_text"; g != w {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the PostgreSQL array naming is updated to use the typename[] syntax as suggested in rows.go, this test expectation should be updated from _text to text[].

Suggested change
if g, w := rpg.ColumnTypeDatabaseTypeName(3), "_text"; g != w {
if g, w := rpg.ColumnTypeDatabaseTypeName(3), "text[]"; g != w {

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

Successfully merging this pull request may close these issues.

1 participant