mirror of
https://github.com/glebarez/go-sqlite.git
synced 2025-10-08 17:20:13 +08:00
add tpch. it builds/runs but it's broken. updates #27.
This commit is contained in:
188
tpch/q.go
Normal file
188
tpch/q.go
Normal file
@@ -0,0 +1,188 @@
|
||||
// Copyright 2032 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"modernc.org/sqlite/tpch/driver"
|
||||
)
|
||||
|
||||
func cpDB(sut driver.SUT, src, dest *sql.DB) error {
|
||||
for _, v := range []struct {
|
||||
t, i string
|
||||
int
|
||||
}{
|
||||
{"_property", sut.InsertProperty(), 3},
|
||||
{"customer", sut.InsertCustomer(), 8},
|
||||
{"lineitem", sut.InsertLineItem(), 16},
|
||||
{"nation", sut.InsertNation(), 4},
|
||||
{"orders", sut.InsertOrders(), 9},
|
||||
{"part", sut.InsertPart(), 9},
|
||||
{"partsupp", sut.InsertPartSupp(), 5},
|
||||
{"region", sut.InsertRegion(), 3},
|
||||
{"supplier", sut.InsertSupplier(), 7},
|
||||
} {
|
||||
if err := cpTable(src, dest, v.t, v.i, v.int); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cpTable(src, dest *sql.DB, tn, ins string, ncols int) (err error) {
|
||||
rows, err := src.Query(fmt.Sprintf("select * from %s", tn))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if e := rows.Close(); e != nil && err == nil {
|
||||
err = e
|
||||
}
|
||||
}()
|
||||
|
||||
var tx *sql.Tx
|
||||
var stmt *sql.Stmt
|
||||
row := make([]interface{}, ncols)
|
||||
data := make([]interface{}, ncols)
|
||||
for i := range data {
|
||||
data[i] = &row[i]
|
||||
}
|
||||
for i := 0; rows.Next(); i++ {
|
||||
if i%1000 == 0 {
|
||||
if i != 0 {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tx, err = dest.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if stmt, err = tx.Prepare(ins); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = rows.Scan(data...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, v := range row {
|
||||
switch x := v.(type) {
|
||||
case time.Time:
|
||||
case int64:
|
||||
case []byte:
|
||||
row[i] = string(x)
|
||||
default:
|
||||
panic("TODO")
|
||||
}
|
||||
}
|
||||
if _, err = stmt.Exec(row...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func run(sut driver.SUT, mem bool, n, sf int, verbose bool) (err error) {
|
||||
pth := pthForSUT(sut, sf)
|
||||
if err := sut.SetWD(pth); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
db, err := sut.OpenDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func(db *sql.DB) {
|
||||
if cerr := db.Close(); cerr != nil && err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}(db)
|
||||
|
||||
if mem {
|
||||
msut, mdb, err := sut.OpenMem()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = msut.CreateTables(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = cpDB(sut, db, mdb); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sut, db = msut, mdb
|
||||
}
|
||||
|
||||
rng := newRng(0, math.MaxInt64)
|
||||
rng.r.Seed(time.Now().UnixNano())
|
||||
t0 := time.Now()
|
||||
|
||||
defer func() {
|
||||
fmt.Println(time.Since(t0)) //TODO -> result.db
|
||||
}()
|
||||
|
||||
switch n {
|
||||
case 1:
|
||||
return exec(db, 10, sut.Q1(), verbose, rng.randomValue(60, 120))
|
||||
case 2:
|
||||
return exec(db, 8, sut.Q2(), verbose, rng.randomValue(1, 50), rng.types(), rng.regions())
|
||||
default:
|
||||
return fmt.Errorf("No query/test #%d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func exec(db *sql.DB, ncols int, q string, verbose bool, arg ...interface{}) error {
|
||||
rec := make([]interface{}, ncols)
|
||||
data := make([]interface{}, ncols)
|
||||
for i := range data {
|
||||
data[i] = &rec[i]
|
||||
}
|
||||
|
||||
rows, err := db.Query(q, arg...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if e := rows.Close(); e != nil && err == nil {
|
||||
err = e
|
||||
}
|
||||
}()
|
||||
|
||||
for rows.Next() {
|
||||
if !verbose {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = rows.Scan(data...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, v := range rec {
|
||||
if b, ok := v.([]byte); ok {
|
||||
rec[i] = string(b)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(rec)
|
||||
}
|
||||
return rows.Err()
|
||||
}
|
Reference in New Issue
Block a user