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

ExecuteWithParameter 支持点插入吗? #208

Closed
minxinqing opened this issue Jun 1, 2022 · 3 comments
Closed

ExecuteWithParameter 支持点插入吗? #208

minxinqing opened this issue Jun 1, 2022 · 3 comments
Labels
type/question Type: question about the product

Comments

@minxinqing
Copy link

minxinqing commented Jun 1, 2022

使用ExecuteWithParameter插入点, 报错。
代码如下:

guild_vid := "guild_11"
params := make(map[string]interface{})
params["p2"] = 111

nGql := fmt.Sprintf(`INSERT VERTEX guild (code) VALUES "%s":($p2);`, guild_vid)

resultSet, err := session.ExecuteWithParameter(nGql, params)

报错如下:

ErrorMsg: Storage Error: The data type does not meet the requirements. Use the correct type of data.

schame如下:

CREATE TAG IF NOT EXISTS guild (
	code int NOT NULL DEFAULT 0 COMMENT '',
	open_id int NOT NULL DEFAULT 0 COMMENT '',
	custom_id string NOT NULL DEFAULT '' COMMENT '',
	name string NOT NULL DEFAULT '' COMMENT '',
	status int NOT NULL DEFAULT 0 COMMENT ''
)
COMMENT = 'xxx';
@Sophie-Xie Sophie-Xie added the type/question Type: question about the product label Nov 30, 2022
@MeneTelk0
Copy link

MeneTelk0 commented Feb 8, 2023

Hi!
Found the similar problem when trying to INSERT VERTEX data into database.

I'm using docker nebula installation - everything is of v3.4.0
nebula-go is also v3.4.0

The example code to reproduce is the following:

package main

import (
	"fmt"
	"sync"

	nebulago "github.com/vesoft-inc/nebula-go/v3"
)

const (
	address = "127.0.0.1"
	// The default port of NebulaGraph 2.x is 9669.
	// 3699 is only for testing.
	port     = 9669
	username = "root"
	password = "nebula"
)

// Initialize logger
var log = nebulago.DefaultLogger{}

func main() {
	hostAddress := nebulago.HostAddress{Host: address, Port: port}
	hostList := []nebulago.HostAddress{hostAddress}
	// Create configs for connection pool using default values
	testPoolConfig := nebulago.GetDefaultConf()

	// Initialize connection pool
	pool, err := nebulago.NewConnectionPool(hostList, testPoolConfig, log)
	if err != nil {
		log.Fatal(fmt.Sprintf("Fail to initialize the connection pool, host: %s, port: %d, %s", address, port, err.Error()))
	}
	// Close all connections in the pool
	defer pool.Close()
	// Create session and send query in go routine
	var wg sync.WaitGroup
	wg.Add(1)
	go func(wg *sync.WaitGroup) {
		defer wg.Done()
		// Create session
		session, err := pool.GetSession(username, password)
		if err != nil {
			log.Fatal(fmt.Sprintf("Fail to create a new session from connection pool, username: %s, password: %s, %s",
				username, password, err.Error()))
		}
		// Release session and return connection back to connection pool
		defer session.Release()

		checkResultSet := func(prefix string, res *nebulago.ResultSet) {
			if !res.IsSucceed() {
				log.Fatal(fmt.Sprintf("%s, ErrorCode: %v, ErrorMsg: %s", prefix, res.GetErrorCode(), res.GetErrorMsg()))
			}
		}

		query := "CREATE SPACE IF NOT EXISTS topology(partition_num=5, replica_factor=1, vid_type=fixed_string(50)); USE topology; CREATE TAG IF NOT EXISTS TEST(testField string);"
		resultSet, err := session.Execute(query)
		if err != nil {
			fmt.Print(err.Error())
			return
		}
		checkResultSet(query, resultSet)

		params := make(map[string]interface{})
		params["p1"] = "hello"

		insertQuery := "INSERT VERTEX TEST(testField) VALUES 'test':($p1)"
		resultSet, err = session.ExecuteWithParameter(insertQuery, params)
		if err != nil {
			fmt.Print(err.Error())
			return
		}
		checkResultSet(insertQuery, resultSet)

	}(&wg)
	wg.Wait()

	fmt.Print("\n")
	log.Info("Nebula Go Parameter Example Finished")
}

I used https://github.com/vesoft-inc/nebula-go/blob/master/examples/parameter_example/parameter_example.go as a base for my example

So, I am creating space topology, afterwards creating simple tag CREATE TAG IF NOT EXISTS TEST(testField string);
And trying to INSERT data with the parametrised query: INSERT VERTEX TEST(testField) VALUES 'test':($p1)

As a result I receive the following error:

[FATAL] INSERT VERTEX TEST(testField) VALUES 'test':($p1), ErrorCode: -1005, ErrorMsg: Storage Error: The data type does not meet the requirements. Use the correct type of data.

Logs in graphd says the following:

E20230208 12:14:03.558832    19 StorageAccessExecutor.h:40] InsertVerticesExecutor failed, error E_DATA_TYPE_MISMATCH, part 2
E20230208 12:14:03.560662    19 QueryInstance.cpp:151] Storage Error: The data type does not meet the requirements. Use the correct type of data., query: INSERT VERTEX TEST(testField) VALUES 'test':($p1)

It seems that we can always create query as a concatenation of strings:

 query := "INSERT VERTEX TEST(testField) VALUES 'test':('" + "HELLO" + "')"

But this pattern makes the code really messy (especially when we have lots of parameters) and vulnerable to SQL Injections. Plus it slows the overall query performance, because we need to construct new query for every new portion of data (in context of using batching for queries), instead of doing it once and justing filling in values.

Appreciate any help!

@czpmango
Copy link
Contributor

@minxinqing @MeneTelk0 Thanks for finding this problem.
Fixed in vesoft-inc/nebula#5328.

@QingZ11
Copy link

QingZ11 commented Mar 30, 2023

这个 issue 超过一个月没有更新内容了,这边先行关闭了。如果你有任何更新的内容,可以再打开这个 issue 哈。

谢谢你的反馈 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/question Type: question about the product
Projects
None yet
Development

No branches or pull requests

5 participants