1package stdlib_test
2
3import (
4	"database/sql"
5	"fmt"
6	"os"
7	"strconv"
8	"strings"
9	"testing"
10	"time"
11)
12
13func getSelectRowsCounts(b *testing.B) []int64 {
14	var rowCounts []int64
15	{
16		s := os.Getenv("PGX_BENCH_SELECT_ROWS_COUNTS")
17		if s != "" {
18			for _, p := range strings.Split(s, " ") {
19				n, err := strconv.ParseInt(p, 10, 64)
20				if err != nil {
21					b.Fatalf("Bad PGX_BENCH_SELECT_ROWS_COUNTS value: %v", err)
22				}
23				rowCounts = append(rowCounts, n)
24			}
25		}
26	}
27
28	if len(rowCounts) == 0 {
29		rowCounts = []int64{1, 10, 100, 1000}
30	}
31
32	return rowCounts
33}
34
35type BenchRowSimple struct {
36	ID         int32
37	FirstName  string
38	LastName   string
39	Sex        string
40	BirthDate  time.Time
41	Weight     int32
42	Height     int32
43	UpdateTime time.Time
44}
45
46func BenchmarkSelectRowsScanSimple(b *testing.B) {
47	db := openDB(b)
48	defer closeDB(b, db)
49
50	rowCounts := getSelectRowsCounts(b)
51
52	for _, rowCount := range rowCounts {
53		b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
54			br := &BenchRowSimple{}
55			for i := 0; i < b.N; i++ {
56				rows, err := db.Query("select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '2001-01-28 01:02:03-05'::timestamptz from generate_series(1, $1) n", rowCount)
57				if err != nil {
58					b.Fatal(err)
59				}
60
61				for rows.Next() {
62					rows.Scan(&br.ID, &br.FirstName, &br.LastName, &br.Sex, &br.BirthDate, &br.Weight, &br.Height, &br.UpdateTime)
63				}
64
65				if rows.Err() != nil {
66					b.Fatal(rows.Err())
67				}
68			}
69		})
70	}
71}
72
73type BenchRowNull struct {
74	ID         sql.NullInt32
75	FirstName  sql.NullString
76	LastName   sql.NullString
77	Sex        sql.NullString
78	BirthDate  sql.NullTime
79	Weight     sql.NullInt32
80	Height     sql.NullInt32
81	UpdateTime sql.NullTime
82}
83
84func BenchmarkSelectRowsScanNull(b *testing.B) {
85	db := openDB(b)
86	defer closeDB(b, db)
87
88	rowCounts := getSelectRowsCounts(b)
89
90	for _, rowCount := range rowCounts {
91		b.Run(fmt.Sprintf("%d rows", rowCount), func(b *testing.B) {
92			br := &BenchRowSimple{}
93			for i := 0; i < b.N; i++ {
94				rows, err := db.Query("select n, 'Adam', 'Smith ' || n, 'male', '1952-06-16'::date, 258, 72, '2001-01-28 01:02:03-05'::timestamptz from generate_series(100000, 100000 +  $1) n", rowCount)
95				if err != nil {
96					b.Fatal(err)
97				}
98
99				for rows.Next() {
100					rows.Scan(&br.ID, &br.FirstName, &br.LastName, &br.Sex, &br.BirthDate, &br.Weight, &br.Height, &br.UpdateTime)
101				}
102
103				if rows.Err() != nil {
104					b.Fatal(rows.Err())
105				}
106			}
107		})
108	}
109}
110