ExecuteWithParameter 支持点插入吗?
minxinqing opened this issue · 3 comments
使用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';
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!
@minxinqing @MeneTelk0 Thanks for finding this problem.
Fixed in vesoft-inc/nebula#5328.
这个 issue 超过一个月没有更新内容了,这边先行关闭了。如果你有任何更新的内容,可以再打开这个 issue 哈。
谢谢你的反馈 😊