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

Failed to support insert data without specify the ts column when using ? placeholder #4244

Closed
zyy17 opened this issue Jul 2, 2024 · 4 comments · Fixed by #4272
Closed

Failed to support insert data without specify the ts column when using ? placeholder #4244

zyy17 opened this issue Jul 2, 2024 · 4 comments · Fixed by #4272
Assignees
Labels
C-bug Category Bugs

Comments

@zyy17
Copy link
Collaborator

zyy17 commented Jul 2, 2024

What type of bug is this?

Unexpected error

What subsystems are affected?

Query Engine

Minimal reproduce step

Test code

I'm using the Go and github.com/go-sql-driver/mysql to connect greptimedb:

package main

import (
	"context"
	"database/sql"

	"github.com/go-sql-driver/mysql"
)

func main() {
	if err := testDB(); err != nil {
		panic(err)
	}
}

func testDB() error {
	cfg := mysql.Config{
		Net:                  "tcp",
		Addr:                 "localhost:4002",
		AllowNativePasswords: true,
	}
	ctx := context.Background()

	db, err := sql.Open("mysql", cfg.FormatDSN())
	if err != nil {
		return err
	}

	conn, err := db.Conn(ctx)
	if err != nil {
		return err
	}

	createStandaloneTableSQL := `CREATE TABLE test_table(
							ts TIMESTAMP DEFAULT current_timestamp(),
							n INT,
							row_id INT,
							PRIMARY KEY(n),
							TIME INDEX (ts)
						  )
						  engine=mito`

	_, err = db.Exec(createStandaloneTableSQL)
	if err != nil {
		return err
	}

	insertDataSQL := `INSERT INTO test_table(n, row_id) VALUES (?, ?);`
	for i := 0; i < 10; i++ {
		_, err = conn.ExecContext(ctx, insertDataSQL, i, i)
		if err != nil {
			return err
		}
	}

	return nil
}

Test steps

  1. Run the greptimedb
docker run -p 127.0.0.1:4000-4003:4000-4003 \
-v "$(pwd)/greptimedb:/tmp/greptimedb" \
--name greptime --rm \
greptime-registry.cn-hangzhou.cr.aliyuncs.com/greptime/greptimedb:v0.8.2 standalone start \
--http-addr 0.0.0.0:4000 \
--rpc-addr 0.0.0.0:4001 \
--mysql-addr 0.0.0.0:4002 \
--postgres-addr 0.0.0.0:4003
  1. Run the test code
go run test-placeholder.go
panic: Error 1815: Invalid request to region 4398046511104(1024, 0), reason: column ts is not null but input has null
...

After multiple tests, the above test failed when the db release version > v0.7.2. It works well in v0.7.2.

  1. Specify the ts column can work
package main

import (
	"context"
	"database/sql"
	"time"

	"github.com/go-sql-driver/mysql"
)

func main() {
	if err := testDB(); err != nil {
		panic(err)
	}
}

func testDB() error {
	cfg := mysql.Config{
		Net:                  "tcp",
		Addr:                 "localhost:4002",
		AllowNativePasswords: true,
	}
	ctx := context.Background()

	db, err := sql.Open("mysql", cfg.FormatDSN())
	if err != nil {
		return err
	}

	conn, err := db.Conn(ctx)
	if err != nil {
		return err
	}

	createStandaloneTableSQL := `CREATE TABLE test_table(
							ts TIMESTAMP DEFAULT current_timestamp(),
							n INT,
							row_id INT,
							PRIMARY KEY(n),
							TIME INDEX (ts)
						  )
						  engine=mito`

	_, err = db.Exec(createStandaloneTableSQL)
	if err != nil {
		return err
	}

	insertDataSQL := `INSERT INTO test_table(n, row_id, ts) VALUES (?, ?, ?);`
	for i := 0; i < 10; i++ {
		now := time.Now()
		timestampInMillisecond := now.Unix()*1000 + int64(now.Nanosecond())/1e6
		_, err = conn.ExecContext(ctx, insertDataSQL, i, i, timestampInMillisecond)
		if err != nil {
			return err
		}
	}

	return nil
}
  1. If I don't use the ? placeholder, it works
package main

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/go-sql-driver/mysql"
)

func main() {
	if err := testDB(); err != nil {
		panic(err)
	}
}

func testDB() error {
	cfg := mysql.Config{
		Net:                  "tcp",
		Addr:                 "localhost:4002",
		AllowNativePasswords: true,
	}
	ctx := context.Background()

	db, err := sql.Open("mysql", cfg.FormatDSN())
	if err != nil {
		return err
	}

	conn, err := db.Conn(ctx)
	if err != nil {
		return err
	}

	createStandaloneTableSQL := `CREATE TABLE test_table(
							ts TIMESTAMP DEFAULT current_timestamp(),
							n INT,
							row_id INT,
							PRIMARY KEY(n),
							TIME INDEX (ts)
						  )
						  engine=mito`

	_, err = db.Exec(createStandaloneTableSQL)
	if err != nil {
		return err
	}

	for i := 0; i < 10; i++ {
		insertDataSQL := fmt.Sprintf("INSERT INTO test_table(n, row_id) VALUES (%d, %d)", i, i)
		_, err = conn.ExecContext(ctx, insertDataSQL)
		if err != nil {
			return err
		}
	}

	return nil
}

What did you expect to see?

The test code should work.

What did you see instead?

The test code failed.

What operating system did you use?

macOS

What version of GreptimeDB did you use?

v0.8.2

Relevant log output and stack trace

No response

@zyy17 zyy17 added the C-bug Category Bugs label Jul 2, 2024
@zyy17
Copy link
Collaborator Author

zyy17 commented Jul 2, 2024

@waynexia @evenyag

@killme2008
Copy link
Contributor

killme2008 commented Jul 3, 2024

Let me figure out.

@killme2008 killme2008 self-assigned this Jul 3, 2024
@killme2008
Copy link
Contributor

Java is good:

Class.forName("com.mysql.cj.jdbc.Driver");
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:4002/public", "root", "password");

		PreparedStatement pstmt = conn.prepareStatement("INSERT INTO test_table(n, row_id) VALUES (?, ?);");

		long start = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			pstmt.setInt(1, i);
			pstmt.setInt(2, i);
			pstmt.addBatch();
			
			if (i % 100 == 0 ){
				pstmt.executeBatch();
			}
		}
		
		pstmt.executeBatch();

Looks like it's related to #4125

@killme2008
Copy link
Contributor

Confirmed:

mysql> prepare stmt1 from 'INSERT INTO test_table(n, row_id) VALUES (?, ?)';
Query OK, 0 rows affected (0.01 sec)

mysql> EXECUTE stmt1 using 1, 1;
ERROR 1815 (HY000): Invalid request to region 4398046511104(1024, 0), reason: column ts is not null but input has null

Let me fix it.

killme2008 added a commit to killme2008/greptimedb that referenced this issue Jul 3, 2024
github-merge-queue bot pushed a commit that referenced this issue Jul 5, 2024
* fix: prepare inserting with column defaults not work, #4244

* fix: build column_defaults every time when creating adapters

* feat: cache the column_defaults in table

* test: assert ts column

* fix: unit

* chore: style

Co-authored-by: Yingwen <realevenyag@gmail.com>

* fix: typo

* chore: style

Co-authored-by: Ruihang Xia <waynestxia@gmail.com>

---------

Co-authored-by: Yingwen <realevenyag@gmail.com>
Co-authored-by: Ruihang Xia <waynestxia@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category Bugs
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants