Add support for materialized views.

This commit is contained in:
go-jet 2024-02-01 15:20:49 +01:00
parent b6d57075e8
commit 7f48e9fb67
8 changed files with 127 additions and 63 deletions

View file

@ -33,6 +33,7 @@ const (
EnumType DataTypeKind = "enum" EnumType DataTypeKind = "enum"
UserDefinedType DataTypeKind = "user-defined" UserDefinedType DataTypeKind = "user-defined"
ArrayType DataTypeKind = "array" ArrayType DataTypeKind = "array"
RangeType DataTypeKind = "range"
) )
// DataType contains information about column data type // DataType contains information about column data type

View file

@ -26,8 +26,25 @@ ORDER BY table_name;
return nil, fmt.Errorf("failed to query %s metadata: %w", tableType, err) return nil, fmt.Errorf("failed to query %s metadata: %w", tableType, err)
} }
// add materialized views separately, because materialized views are not part of standard information schema
if tableType == metadata.ViewTable {
matViewQuery := `
select matviewname as "table.name"
from pg_matviews
where schemaname = $1;
`
var matViews []metadata.Table
_, err := qrm.Query(context.Background(), db, matViewQuery, []interface{}{schemaName}, &matViews)
if err != nil {
return nil, fmt.Errorf("failed to query materialized view metadata: %w", err)
}
tables = append(tables, matViews...)
}
for i := range tables { for i := range tables {
tables[i].Columns, err = p.GetTableColumnsMetaData(db, schemaName, tables[i].Name) tables[i].Columns, err = getColumnsMetaData(db, schemaName, tables[i].Name)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to query %s columns metadata: %w", tableType, err) return nil, fmt.Errorf("failed to query %s columns metadata: %w", tableType, err)
} }
@ -36,39 +53,39 @@ ORDER BY table_name;
return tables, nil return tables, nil
} }
func (p postgresQuerySet) GetTableColumnsMetaData(db *sql.DB, schemaName string, tableName string) ([]metadata.Column, error) { func getColumnsMetaData(db *sql.DB, schemaName string, tableName string) ([]metadata.Column, error) {
query := ` query := `
WITH primaryKeys AS ( select
SELECT column_name attr.attname as "column.Name",
FROM information_schema.key_column_usage AS c exists(
LEFT JOIN information_schema.table_constraints AS t select 1
ON t.constraint_name = c.constraint_name AND from pg_catalog.pg_index indx
c.table_schema = t.table_schema AND where attr.attrelid = indx.indrelid and attr.attnum = any(indx.indkey) and indx.indisprimary
c.table_name = t.table_name ) as "column.IsPrimaryKey",
WHERE t.table_schema = $1 AND t.table_name = $2 AND t.constraint_type = 'PRIMARY KEY' not attr.attnotnull as "column.isNullable",
) attr.attgenerated = 's' as "column.isGenerated",
SELECT column_name as "column.Name", (case tp.typtype
is_nullable = 'YES' as "column.isNullable", when 'b' then 'base'
is_generated = 'ALWAYS' or is_generated = 'YES' as "column.isGenerated", when 'd' then 'base'
(EXISTS(SELECT 1 from primaryKeys as pk where pk.column_name = columns.column_name)) as "column.IsPrimaryKey", when 'e' then 'enum'
dataType.kind as "dataType.Kind", when 'r' then 'range'
(case dataType.Kind when 'base' then data_type else LTRIM(udt_name, '_') end) as "dataType.Name", end) as "dataType.Kind",
FALSE as "dataType.isUnsigned" (case when tp.typtype = 'd' then (select pg_type.typname from pg_catalog.pg_type where pg_type.oid = tp.typbasetype)
FROM information_schema.columns, when tp.typcategory = 'A' then pg_catalog.format_type(attr.atttypid, attr.atttypmod)
LATERAL (select (case data_type else tp.typname
when 'ARRAY' then 'array' end) as "dataType.Name",
when 'USER-DEFINED' then false as "dataType.isUnsigned"
case (select t.typtype from pg_catalog.pg_attribute as attr
from pg_type as t join pg_catalog.pg_class as cls on cls.oid = attr.attrelid
join pg_namespace as p on p.oid = t.typnamespace join pg_catalog.pg_namespace as ns on ns.oid = cls.relnamespace
where t.typname = columns.udt_name and p.nspname = $1) join pg_catalog.pg_type as tp on tp.oid = attr.atttypid
when 'e' then 'enum' where
else 'user-defined' ns.nspname = $1 and
end cls.relname = $2 and
else 'base' not attr.attisdropped and
end) as Kind) as dataType attr.attnum > 0
where table_schema = $1 and table_name = $2 order by
order by ordinal_position; attr.attnum;
` `
var columns []metadata.Column var columns []metadata.Column
_, err := qrm.Query(context.Background(), db, query, []interface{}{schemaName, tableName}, &columns) _, err := qrm.Query(context.Background(), db, query, []interface{}{schemaName, tableName}, &columns)

View file

@ -142,14 +142,15 @@ func DefaultTableSQLBuilderColumn(columnMetaData metadata.Column) TableSQLBuilde
// getSqlBuilderColumnType returns type of jet sql builder column // getSqlBuilderColumnType returns type of jet sql builder column
func getSqlBuilderColumnType(columnMetaData metadata.Column) string { func getSqlBuilderColumnType(columnMetaData metadata.Column) string {
if columnMetaData.DataType.Kind != metadata.BaseType { if columnMetaData.DataType.Kind != metadata.BaseType &&
columnMetaData.DataType.Kind != metadata.RangeType {
return "String" return "String"
} }
switch strings.ToLower(columnMetaData.DataType.Name) { switch strings.ToLower(columnMetaData.DataType.Name) {
case "boolean": case "boolean", "bool":
return "Bool" return "Bool"
case "smallint", "integer", "bigint", case "smallint", "integer", "bigint", "int2", "int4", "int8",
"tinyint", "mediumint", "int", "year": //MySQL "tinyint", "mediumint", "int", "year": //MySQL
return "Integer" return "Integer"
case "date": case "date":
@ -157,21 +158,21 @@ func getSqlBuilderColumnType(columnMetaData metadata.Column) string {
case "timestamp without time zone", case "timestamp without time zone",
"timestamp", "datetime": //MySQL: "timestamp", "datetime": //MySQL:
return "Timestamp" return "Timestamp"
case "timestamp with time zone": case "timestamp with time zone", "timestamptz":
return "Timestampz" return "Timestampz"
case "time without time zone", case "time without time zone",
"time": //MySQL "time": //MySQL
return "Time" return "Time"
case "time with time zone": case "time with time zone", "timetz":
return "Timez" return "Timez"
case "interval": case "interval":
return "Interval" return "Interval"
case "user-defined", "enum", "text", "character", "character varying", "bytea", "uuid", case "user-defined", "enum", "text", "character", "character varying", "bytea", "uuid",
"tsvector", "bit", "bit varying", "money", "json", "jsonb", "xml", "point", "line", "ARRAY", "tsvector", "bit", "bit varying", "money", "json", "jsonb", "xml", "point", "line", "ARRAY",
"char", "varchar", "nvarchar", "binary", "varbinary", "char", "varchar", "nvarchar", "binary", "varbinary", "bpchar", "varbit",
"tinyblob", "blob", "mediumblob", "longblob", "tinytext", "mediumtext", "longtext": // MySQL "tinyblob", "blob", "mediumblob", "longblob", "tinytext", "mediumtext", "longtext": // MySQL
return "String" return "String"
case "real", "numeric", "decimal", "double precision", "float", case "real", "numeric", "decimal", "double precision", "float", "float4", "float8",
"double": // MySQL "double": // MySQL
return "Float" return "Float"
default: default:

View file

@ -39,14 +39,14 @@ services:
- ./testdata/init/mysql:/docker-entrypoint-initdb.d - ./testdata/init/mysql:/docker-entrypoint-initdb.d
cockroach: cockroach:
image: cockroachdb/cockroach-unstable:v22.1.0-beta.4 image: cockroachdb/cockroach-unstable:v23.1.0-rc.2
environment: environment:
- COCKROACH_USER=jet - COCKROACH_USER=jet
- COCKROACH_PASSWORD=jet - COCKROACH_PASSWORD=jet
- COCKROACH_DATABASE=jetdb - COCKROACH_DATABASE=jetdb
ports: ports:
- "26257:26257" - "26257:26257"
command: start-single-node --insecure command: start-single-node --accept-sql-without-tls
# volumes: # volumes:
# - ./testdata/init/cockroach:/docker-entrypoint-initdb.d # - ./testdata/init/cockroach:/docker-entrypoint-initdb.d

View file

@ -17,31 +17,52 @@ import (
"github.com/go-jet/jet/v2/tests/testdata/results/common" "github.com/go-jet/jet/v2/tests/testdata/results/common"
) )
var AllTypesAllColumns = AllTypes.AllColumns.
Except(IntegerColumn("rowid")) // cockroachDB: exclude rowid column
func TestAllTypesSelect(t *testing.T) { func TestAllTypesSelect(t *testing.T) {
var dest []model.AllTypes var dest []model.AllTypes
err := AllTypes.SELECT( err := AllTypes.SELECT(AllTypesAllColumns).
AllTypesAllColumns, LIMIT(2).
).LIMIT(2).
Query(db, &dest) Query(db, &dest)
require.NoError(t, err)
require.NoError(t, err)
testutils.AssertDeepEqual(t, dest[0], allTypesRow0) testutils.AssertDeepEqual(t, dest[0], allTypesRow0)
testutils.AssertDeepEqual(t, dest[1], allTypesRow1) testutils.AssertDeepEqual(t, dest[1], allTypesRow1)
} }
func TestAllTypesViewSelect(t *testing.T) { func TestAllTypesViewSelect(t *testing.T) {
type AllTypesView model.AllTypes type AllTypesView model.AllTypes
var dest []AllTypesView var dest []AllTypesView
err := view.AllTypesView.SELECT(view.AllTypesView.AllColumns).Query(db, &dest) err := SELECT(view.AllTypesView.AllColumns).
require.NoError(t, err) FROM(view.AllTypesView).
Query(db, &dest)
require.NoError(t, err)
testutils.AssertDeepEqual(t, dest[0], AllTypesView(allTypesRow0)) testutils.AssertDeepEqual(t, dest[0], AllTypesView(allTypesRow0))
testutils.AssertDeepEqual(t, dest[1], AllTypesView(allTypesRow1)) testutils.AssertDeepEqual(t, dest[1], AllTypesView(allTypesRow1))
} }
func TestMaterializedViewAllTypes(t *testing.T) {
stmt := SELECT(
view.AllTypesMaterializedView.AllColumns.
Except(IntegerColumn("rowid")), // cockroachDB: exclude rowid column
).FROM(
view.AllTypesMaterializedView,
)
type AllTypesMaterializedView model.AllTypes
var dest []AllTypesMaterializedView
err := stmt.Query(db, &dest)
require.NoError(t, err)
testutils.AssertDeepEqual(t, dest[0], AllTypesMaterializedView(allTypesRow0))
testutils.AssertDeepEqual(t, dest[1], AllTypesMaterializedView(allTypesRow1))
}
func TestAllTypesInsertModel(t *testing.T) { func TestAllTypesInsertModel(t *testing.T) {
skipForPgxDriver(t) // pgx driver bug ERROR: date/time field value out of range: "0000-01-01 12:05:06Z" (SQLSTATE 22008) skipForPgxDriver(t) // pgx driver bug ERROR: date/time field value out of range: "0000-01-01 12:05:06Z" (SQLSTATE 22008)
@ -64,8 +85,6 @@ func TestAllTypesInsertModel(t *testing.T) {
}) })
} }
var AllTypesAllColumns = AllTypes.AllColumns.Except(IntegerColumn("rowid"))
func TestAllTypesInsertQuery(t *testing.T) { func TestAllTypesInsertQuery(t *testing.T) {
query := AllTypes.INSERT(AllTypesAllColumns). query := AllTypes.INSERT(AllTypesAllColumns).
QUERY( QUERY(
@ -230,7 +249,9 @@ SELECT "allTypesSubQuery"."all_types.small_int_ptr" AS "all_types.small_int_ptr"
"allTypesSubQuery"."all_types.text_array" AS "all_types.text_array", "allTypesSubQuery"."all_types.text_array" AS "all_types.text_array",
"allTypesSubQuery"."all_types.jsonb_array" AS "all_types.jsonb_array", "allTypesSubQuery"."all_types.jsonb_array" AS "all_types.jsonb_array",
"allTypesSubQuery"."all_types.text_multi_dim_array_ptr" AS "all_types.text_multi_dim_array_ptr", "allTypesSubQuery"."all_types.text_multi_dim_array_ptr" AS "all_types.text_multi_dim_array_ptr",
"allTypesSubQuery"."all_types.text_multi_dim_array" AS "all_types.text_multi_dim_array" "allTypesSubQuery"."all_types.text_multi_dim_array" AS "all_types.text_multi_dim_array",
"allTypesSubQuery"."all_types.mood_ptr" AS "all_types.mood_ptr",
"allTypesSubQuery"."all_types.mood" AS "all_types.mood"
FROM ( FROM (
SELECT all_types.small_int_ptr AS "all_types.small_int_ptr", SELECT all_types.small_int_ptr AS "all_types.small_int_ptr",
all_types.small_int AS "all_types.small_int", all_types.small_int AS "all_types.small_int",
@ -292,7 +313,9 @@ FROM (
all_types.text_array AS "all_types.text_array", all_types.text_array AS "all_types.text_array",
all_types.jsonb_array AS "all_types.jsonb_array", all_types.jsonb_array AS "all_types.jsonb_array",
all_types.text_multi_dim_array_ptr AS "all_types.text_multi_dim_array_ptr", all_types.text_multi_dim_array_ptr AS "all_types.text_multi_dim_array_ptr",
all_types.text_multi_dim_array AS "all_types.text_multi_dim_array" all_types.text_multi_dim_array AS "all_types.text_multi_dim_array",
all_types.mood_ptr AS "all_types.mood_ptr",
all_types.mood AS "all_types.mood"
FROM test_sample.all_types FROM test_sample.all_types
) AS "allTypesSubQuery" ) AS "allTypesSubQuery"
LIMIT 2; LIMIT 2;
@ -1279,6 +1302,8 @@ RETURNING all_types.json AS "all_types.json";
}) })
} }
var moodSad = model.Mood_Sad
var allTypesRow0 = model.AllTypes{ var allTypesRow0 = model.AllTypes{
SmallIntPtr: testutils.Int16Ptr(14), SmallIntPtr: testutils.Int16Ptr(14),
SmallInt: 14, SmallInt: 14,
@ -1343,6 +1368,8 @@ var allTypesRow0 = model.AllTypes{
JsonbArray: `{"{\"a\": 1, \"b\": 2}","{\"a\": 3, \"b\": 4}"}`, JsonbArray: `{"{\"a\": 1, \"b\": 2}","{\"a\": 3, \"b\": 4}"}`,
TextMultiDimArrayPtr: testutils.StringPtr("{{meeting,lunch},{training,presentation}}"), TextMultiDimArrayPtr: testutils.StringPtr("{{meeting,lunch},{training,presentation}}"),
TextMultiDimArray: "{{meeting,lunch},{training,presentation}}", TextMultiDimArray: "{{meeting,lunch},{training,presentation}}",
MoodPtr: &moodSad,
Mood: model.Mood_Happy,
} }
var allTypesRow1 = model.AllTypes{ var allTypesRow1 = model.AllTypes{
@ -1409,6 +1436,8 @@ var allTypesRow1 = model.AllTypes{
JsonbArray: `{"{\"a\": 1, \"b\": 2}","{\"a\": 3, \"b\": 4}"}`, JsonbArray: `{"{\"a\": 1, \"b\": 2}","{\"a\": 3, \"b\": 4}"}`,
TextMultiDimArrayPtr: nil, TextMultiDimArrayPtr: nil,
TextMultiDimArray: "{{meeting,lunch},{training,presentation}}", TextMultiDimArray: "{{meeting,lunch},{training,presentation}}",
MoodPtr: nil,
Mood: model.Mood_Ok,
} }
func TestAliasedDuplicateSliceSubType(t *testing.T) { func TestAliasedDuplicateSliceSubType(t *testing.T) {

View file

@ -548,11 +548,12 @@ func UseSchema(schema string) {
` `
func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) { func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
skipForCockroachDB(t) skipForCockroachDB(t) // because of rowid column
enumDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/enum/") enumDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/enum/")
modelDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/model/") modelDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/model/")
tableDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/table/") tableDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/table/")
viewDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/view/")
testutils.AssertFileNamesEqual(t, enumDir, "mood.go", "level.go") testutils.AssertFileNamesEqual(t, enumDir, "mood.go", "level.go")
testutils.AssertFileContent(t, enumDir+"/mood.go", moodEnumContent) testutils.AssertFileContent(t, enumDir+"/mood.go", moodEnumContent)
@ -560,15 +561,16 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
testutils.AssertFileNamesEqual(t, modelDir, "all_types.go", "all_types_view.go", "employee.go", "link.go", testutils.AssertFileNamesEqual(t, modelDir, "all_types.go", "all_types_view.go", "employee.go", "link.go",
"mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go", "people.go", "mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go", "people.go",
"components.go", "vulnerabilities.go") "components.go", "vulnerabilities.go", "all_types_materialized_view.go")
testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent) testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent)
testutils.AssertFileNamesEqual(t, tableDir, "all_types.go", "employee.go", "link.go", testutils.AssertFileNamesEqual(t, tableDir, "all_types.go", "employee.go", "link.go",
"person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go", "people.go", "table_use_schema.go", "person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go", "people.go", "table_use_schema.go",
"components.go", "vulnerabilities.go") "components.go", "vulnerabilities.go")
testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent) testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent)
testutils.AssertFileNamesEqual(t, viewDir, "all_types_materialized_view.go", "all_types_view.go",
"view_use_schema.go")
} }
var moodEnumContent = ` var moodEnumContent = `
@ -698,6 +700,8 @@ type AllTypes struct {
JsonbArray string JsonbArray string
TextMultiDimArrayPtr *string TextMultiDimArrayPtr *string
TextMultiDimArray string TextMultiDimArray string
MoodPtr *Mood
Mood Mood
} }
` `
@ -782,6 +786,8 @@ type allTypesTable struct {
JsonbArray postgres.ColumnString JsonbArray postgres.ColumnString
TextMultiDimArrayPtr postgres.ColumnString TextMultiDimArrayPtr postgres.ColumnString
TextMultiDimArray postgres.ColumnString TextMultiDimArray postgres.ColumnString
MoodPtr postgres.ColumnString
Mood postgres.ColumnString
AllColumns postgres.ColumnList AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList MutableColumns postgres.ColumnList
@ -883,8 +889,10 @@ func newAllTypesTableImpl(schemaName, tableName, alias string) allTypesTable {
JsonbArrayColumn = postgres.StringColumn("jsonb_array") JsonbArrayColumn = postgres.StringColumn("jsonb_array")
TextMultiDimArrayPtrColumn = postgres.StringColumn("text_multi_dim_array_ptr") TextMultiDimArrayPtrColumn = postgres.StringColumn("text_multi_dim_array_ptr")
TextMultiDimArrayColumn = postgres.StringColumn("text_multi_dim_array") TextMultiDimArrayColumn = postgres.StringColumn("text_multi_dim_array")
allColumns = postgres.ColumnList{SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn} MoodPtrColumn = postgres.StringColumn("mood_ptr")
mutableColumns = postgres.ColumnList{SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn} MoodColumn = postgres.StringColumn("mood")
allColumns = postgres.ColumnList{SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn, MoodPtrColumn, MoodColumn}
mutableColumns = postgres.ColumnList{SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn, MoodPtrColumn, MoodColumn}
) )
return allTypesTable{ return allTypesTable{
@ -952,6 +960,8 @@ func newAllTypesTableImpl(schemaName, tableName, alias string) allTypesTable {
JsonbArray: JsonbArrayColumn, JsonbArray: JsonbArrayColumn,
TextMultiDimArrayPtr: TextMultiDimArrayPtrColumn, TextMultiDimArrayPtr: TextMultiDimArrayPtrColumn,
TextMultiDimArray: TextMultiDimArrayColumn, TextMultiDimArray: TextMultiDimArrayColumn,
MoodPtr: MoodPtrColumn,
Mood: MoodColumn,
AllColumns: allColumns, AllColumns: allColumns,
MutableColumns: mutableColumns, MutableColumns: mutableColumns,

View file

@ -120,9 +120,15 @@ RETURNING floats.decimal_ptr AS "floats.decimal_ptr",
} }
func TestUUIDComplex(t *testing.T) { func TestUUIDComplex(t *testing.T) {
query := Person.INNER_JOIN(PersonPhone, PersonPhone.PersonID.EQ(Person.PersonID)). query := SELECT(
SELECT(Person.AllColumns, PersonPhone.AllColumns). Person.AllColumns,
ORDER_BY(Person.PersonID.ASC(), PersonPhone.PhoneID.ASC()) PersonPhone.AllColumns,
).FROM(
Person.INNER_JOIN(PersonPhone, PersonPhone.PersonID.EQ(Person.PersonID)),
).ORDER_BY(
Person.PersonID.ASC(),
PersonPhone.PhoneID.ASC(),
)
t.Run("slice of structs", func(t *testing.T) { t.Run("slice of structs", func(t *testing.T) {

@ -1 +1 @@
Subproject commit 3398b9735b9d097d2ee0c282976726affc6b96f0 Subproject commit b2f98e8297c34e86e02ada4226c125de53f64a6d