/src/magpie/eval/sql.go

https://github.com/haifenghuang/magpie · Go · 755 lines · 562 code · 111 blank · 82 comment · 121 complexity · 73c13f54285c971d56493d994c15967c MD5 · raw file

  1. package eval
  2. import (
  3. "database/sql"
  4. _ "fmt"
  5. // _ "github.com/mattn/go-sqlite3"
  6. _ "reflect"
  7. )
  8. const (
  9. DBSQL_OBJ = "DBSQL_OBJ" //sql object
  10. DBRESULT_OBJ = "DBRESULT_OBJ" //result object
  11. DBROW_OBJ = "DBROW_OBJ" //row object
  12. DBROWS_OBJ = "DBROWS_OBJ" //rows object
  13. DBSTMT_OBJ = "DBSTMT_OBJ" //statement object
  14. DBTX_OBJ = "DBTX_OBJ" //transaction object
  15. )
  16. const (
  17. SQL_OBJ = "SQL_OBJ"
  18. sql_name = "sql"
  19. )
  20. //This object's purpose is only for 5 predefined null constants
  21. type SqlsObject struct {
  22. }
  23. func (s *SqlsObject) Inspect() string { return "<" + sql_name + ">" }
  24. func (s *SqlsObject) Type() ObjectType { return SQL_OBJ }
  25. func (s *SqlsObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  26. return NewError(line, NOMETHODERROR, method, s.Type())
  27. }
  28. func NewSqlsObject() Object {
  29. ret := &SqlsObject{}
  30. SetGlobalObj(sql_name, ret)
  31. //Below five variables are mainly used in `sql` handling.
  32. //when we want to insert null to a certain column, we could
  33. //use these variables
  34. SetGlobalObj(sql_name+".INT_NULL", &Integer{Int64: 0, Valid: false}) //NullInteger
  35. SetGlobalObj(sql_name+".UINT_NULL", &UInteger{UInt64: 0, Valid: false}) //NullUInteger
  36. SetGlobalObj(sql_name+".FLOAT_NULL", &Float{Float64: 0.0, Valid: false}) //NullFloat
  37. SetGlobalObj(sql_name+".STRING_NULL", &String{String: "", Valid: false}) //NullString
  38. SetGlobalObj(sql_name+".BOOL_NULL", &Boolean{Bool: true, Valid: false}) //NullBool
  39. SetGlobalObj(sql_name+".TIME_NULL", &TimeObj{Valid: false}) //NullTime
  40. SetGlobalObj(sql_name+".DECIMAL_NULL", &DecimalObj{Valid: false}) //NullDecimal
  41. return ret
  42. }
  43. //***************************************************************
  44. // SQL Object
  45. //***************************************************************
  46. type SqlObject struct {
  47. Db *sql.DB
  48. Name string
  49. }
  50. // Implement the 'Closeable' interface
  51. func (s *SqlObject) close(line string, args ...Object) Object {
  52. return s.Close(line, args...)
  53. }
  54. func (s *SqlObject) Inspect() string { return s.Name }
  55. func (s *SqlObject) Type() ObjectType { return DBSQL_OBJ }
  56. func (s *SqlObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  57. switch method {
  58. case "ping":
  59. return s.Ping(line, args...)
  60. case "close":
  61. return s.Close(line, args...)
  62. case "setMaxOpenConns":
  63. return s.SetMaxOpenConns(line, args...)
  64. case "setMaxIdleConns":
  65. return s.SetMaxIdleConns(line, args...)
  66. case "exec":
  67. return s.Exec(line, args...)
  68. case "query":
  69. return s.Query(line, args...)
  70. case "queryRow":
  71. return s.QueryRow(line, args...)
  72. case "prepare":
  73. return s.Prepare(line, args...)
  74. case "begin":
  75. return s.Begin(line, args...)
  76. default:
  77. return NewError(line, NOMETHODERROR, method, s.Type())
  78. }
  79. }
  80. //Return the remote address
  81. func (s *SqlObject) Ping(line string, args ...Object) Object {
  82. if len(args) != 0 {
  83. return NewError(line, ARGUMENTERROR, "0", len(args))
  84. }
  85. err := s.Db.Ping()
  86. if err != nil {
  87. return NewFalseObj(err.Error())
  88. }
  89. return TRUE
  90. }
  91. func (s *SqlObject) Close(line string, args ...Object) Object {
  92. if len(args) != 0 {
  93. return NewError(line, ARGUMENTERROR, "0", len(args))
  94. }
  95. err := s.Db.Close()
  96. if err != nil {
  97. return NewFalseObj(err.Error())
  98. }
  99. return TRUE
  100. }
  101. func (s *SqlObject) SetMaxOpenConns(line string, args ...Object) Object {
  102. if len(args) != 1 {
  103. return NewError(line, ARGUMENTERROR, "0", len(args))
  104. }
  105. n, ok := args[0].(*Integer)
  106. if !ok {
  107. return NewError(line, PARAMTYPEERROR, "first", "setMaxOpenConns", "*Integer", args[0].Type())
  108. }
  109. s.Db.SetMaxOpenConns(int(n.Int64))
  110. return NIL
  111. }
  112. func (s *SqlObject) SetMaxIdleConns(line string, args ...Object) Object {
  113. if len(args) != 1 {
  114. return NewError(line, ARGUMENTERROR, "0", len(args))
  115. }
  116. n, ok := args[0].(*Integer)
  117. if !ok {
  118. return NewError(line, PARAMTYPEERROR, "first", "setMaxIdleConns", "*Integer", args[0].Type())
  119. }
  120. s.Db.SetMaxIdleConns(int(n.Int64))
  121. return NIL
  122. }
  123. func (s *SqlObject) Exec(line string, args ...Object) Object {
  124. if len(args) < 1 {
  125. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  126. }
  127. query, ok := args[0].(*String)
  128. if !ok {
  129. return NewError(line, PARAMTYPEERROR, "first", "exec", "*String", args[0].Type())
  130. }
  131. var params []interface{}
  132. if len(args) > 1 {
  133. params = handleExecParams(args[1:])
  134. if params == nil {
  135. return NewError(line, INVALIDARG)
  136. }
  137. }
  138. result, err := s.Db.Exec(query.String, params...)
  139. if err != nil {
  140. return NewNil(err.Error())
  141. }
  142. return &DbResultObject{Result: result, Name: s.Name}
  143. }
  144. func (s *SqlObject) Query(line string, args ...Object) Object {
  145. if len(args) < 1 {
  146. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  147. }
  148. query, ok := args[0].(*String)
  149. if !ok {
  150. return NewError(line, PARAMTYPEERROR, "first", "query", "*String", args[0].Type())
  151. }
  152. var params []interface{}
  153. arr := args[1:]
  154. for idx, arg := range arr {
  155. _, ok := arg.(*String)
  156. if !ok {
  157. return NewError(line, PARAMTYPEERROR, "remaining", "query", "*String", arr[idx].Type())
  158. }
  159. params = append(params, arg.Inspect())
  160. }
  161. rows, err := s.Db.Query(query.String, params...)
  162. if err != nil {
  163. return NewNil(err.Error())
  164. }
  165. return &DbRowsObject{Rows: rows, Name: s.Name}
  166. }
  167. func (s *SqlObject) QueryRow(line string, args ...Object) Object {
  168. if len(args) < 1 {
  169. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  170. }
  171. query, ok := args[0].(*String)
  172. if !ok {
  173. return NewError(line, PARAMTYPEERROR, "first", "queryRow", "*String", args[0].Type())
  174. }
  175. var params []interface{}
  176. arr := args[1:]
  177. for idx, arg := range arr {
  178. _, ok := arg.(*String)
  179. if !ok {
  180. return NewError(line, PARAMTYPEERROR, "remaining", "queryRow", "*String", arr[idx].Type())
  181. }
  182. params = append(params, arg.Inspect())
  183. }
  184. row := s.Db.QueryRow(query.String, params...)
  185. return &DbRowObject{Row: row, Name: s.Name}
  186. }
  187. func (s *SqlObject) Prepare(line string, args ...Object) Object {
  188. if len(args) != 1 {
  189. return NewError(line, ARGUMENTERROR, "1", len(args))
  190. }
  191. query, ok := args[0].(*String)
  192. if !ok {
  193. return NewError(line, PARAMTYPEERROR, "first", "prepare", "*String", args[0].Type())
  194. }
  195. stmt, err := s.Db.Prepare(query.String)
  196. if err != nil {
  197. return NewNil(err.Error())
  198. }
  199. return &DbStmtObject{Stmt: stmt, Name: s.Name}
  200. }
  201. func (s *SqlObject) Begin(line string, args ...Object) Object {
  202. if len(args) != 0 {
  203. return NewError(line, ARGUMENTERROR, "0", len(args))
  204. }
  205. tx, err := s.Db.Begin()
  206. if err != nil {
  207. return NewNil(err.Error())
  208. }
  209. return &DbTxObject{Tx: tx, Name: s.Name}
  210. }
  211. //***************************************************************
  212. // DB Result Object
  213. //***************************************************************
  214. type DbResultObject struct {
  215. Result sql.Result
  216. Name string
  217. }
  218. func (r *DbResultObject) Inspect() string { return r.Name }
  219. func (r *DbResultObject) Type() ObjectType { return DBRESULT_OBJ }
  220. func (r *DbResultObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  221. switch method {
  222. case "lastInsertId":
  223. return r.LastInsertId(line, args...)
  224. case "rowsAffected":
  225. return r.RowsAffected(line, args...)
  226. default:
  227. return NewError(line, NOMETHODERROR, method, r.Type())
  228. }
  229. }
  230. func (r *DbResultObject) LastInsertId(line string, args ...Object) Object {
  231. n, err := r.Result.LastInsertId()
  232. if err != nil {
  233. return NewInteger(-1)
  234. }
  235. return NewInteger(n)
  236. }
  237. func (r *DbResultObject) RowsAffected(line string, args ...Object) Object {
  238. n, err := r.Result.RowsAffected()
  239. if err != nil {
  240. return NewInteger(-1)
  241. }
  242. return NewInteger(n)
  243. }
  244. //***************************************************************
  245. // DB Rows Object
  246. //***************************************************************
  247. type DbRowsObject struct {
  248. Rows *sql.Rows
  249. Name string
  250. }
  251. // Implement the 'Closeable' interface
  252. func (r *DbRowsObject) close(line string, args ...Object) Object {
  253. return r.Close(line, args...)
  254. }
  255. func (r *DbRowsObject) Inspect() string { return r.Name }
  256. func (r *DbRowsObject) Type() ObjectType { return DBROWS_OBJ }
  257. func (r *DbRowsObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  258. switch method {
  259. case "columns":
  260. return r.Columns(line, args...)
  261. case "scan":
  262. return r.Scan(line, args...)
  263. case "next":
  264. return r.Next(line, args...)
  265. case "close":
  266. return r.Close(line, args...)
  267. case "err":
  268. return r.Err(line, args...)
  269. default:
  270. return NewError(line, NOMETHODERROR, method, r.Type())
  271. }
  272. }
  273. func (r *DbRowsObject) Columns(line string, args ...Object) Object {
  274. if len(args) != 0 {
  275. return NewError(line, ARGUMENTERROR, "0", len(args))
  276. }
  277. arr := &Array{}
  278. cols, err := r.Rows.Columns()
  279. if err != nil {
  280. return NewNil(err.Error())
  281. }
  282. for _, col := range cols {
  283. arr.Members = append(arr.Members, NewString(col))
  284. }
  285. return arr
  286. }
  287. func (r *DbRowsObject) Scan(line string, args ...Object) Object {
  288. return scan(r.Rows, line, args...)
  289. }
  290. func (r *DbRowsObject) Next(line string, args ...Object) Object {
  291. if len(args) != 0 {
  292. return NewError(line, ARGUMENTERROR, "0", len(args))
  293. }
  294. b := r.Rows.Next()
  295. if b {
  296. return TRUE
  297. }
  298. return FALSE
  299. }
  300. func (r *DbRowsObject) Close(line string, args ...Object) Object {
  301. if len(args) != 0 {
  302. return NewError(line, ARGUMENTERROR, "0", len(args))
  303. }
  304. err := r.Rows.Close()
  305. if err != nil {
  306. return NewFalseObj(err.Error())
  307. }
  308. return TRUE
  309. }
  310. func (r *DbRowsObject) Err(line string, args ...Object) Object {
  311. if len(args) != 0 {
  312. return NewError(line, ARGUMENTERROR, "0", len(args))
  313. }
  314. err := r.Rows.Err()
  315. if err != nil {
  316. return NewString(err.Error())
  317. }
  318. return NewString("")
  319. }
  320. //***************************************************************
  321. // DB Row Object
  322. //***************************************************************
  323. type DbRowObject struct {
  324. Row *sql.Row
  325. Name string
  326. }
  327. func (r *DbRowObject) Inspect() string { return r.Name }
  328. func (r *DbRowObject) Type() ObjectType { return DBROW_OBJ }
  329. func (r *DbRowObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  330. switch method {
  331. case "scan":
  332. return r.Scan(line, args...)
  333. default:
  334. return NewError(line, NOMETHODERROR, method, r.Type())
  335. }
  336. }
  337. func (r *DbRowObject) Scan(line string, args ...Object) Object {
  338. return scan(r.Row, line, args...)
  339. }
  340. //***************************************************************
  341. // DB Statement Object
  342. //***************************************************************
  343. type DbStmtObject struct {
  344. Stmt *sql.Stmt
  345. Name string
  346. }
  347. // Implement the 'Closeable' interface
  348. func (s *DbStmtObject) close(line string, args ...Object) Object {
  349. return s.Close(line, args...)
  350. }
  351. func (s *DbStmtObject) Inspect() string { return s.Name }
  352. func (s *DbStmtObject) Type() ObjectType { return DBSTMT_OBJ }
  353. func (s *DbStmtObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  354. switch method {
  355. case "exec":
  356. return s.Exec(line, args...)
  357. case "query":
  358. return s.Query(line, args...)
  359. case "queryRow":
  360. return s.QueryRow(line, args...)
  361. case "close":
  362. return s.Close(line, args...)
  363. default:
  364. return NewError(line, NOMETHODERROR, method, s.Type())
  365. }
  366. }
  367. func (s *DbStmtObject) Close(line string, args ...Object) Object {
  368. if len(args) != 0 {
  369. return NewError(line, ARGUMENTERROR, "0", len(args))
  370. }
  371. err := s.Stmt.Close()
  372. if err != nil {
  373. return NewFalseObj(err.Error())
  374. }
  375. return TRUE
  376. }
  377. func (s *DbStmtObject) Exec(line string, args ...Object) Object {
  378. if len(args) < 1 {
  379. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  380. }
  381. params := handleExecParams(args)
  382. if params == nil {
  383. return NewError(line, INVALIDARG)
  384. }
  385. result, err := s.Stmt.Exec(params...)
  386. if err != nil {
  387. return NewNil(err.Error())
  388. }
  389. return &DbResultObject{Result: result, Name: s.Name}
  390. }
  391. func (s *DbStmtObject) Query(line string, args ...Object) Object {
  392. var params []interface{}
  393. for idx, arg := range args {
  394. _, ok := arg.(*String)
  395. if !ok {
  396. return NewError(line, PARAMTYPEERROR, "All", "query", "*String", args[idx].Type())
  397. }
  398. params = append(params, arg.Inspect())
  399. }
  400. rows, err := s.Stmt.Query(params...)
  401. if err != nil {
  402. return NewNil(err.Error())
  403. }
  404. return &DbRowsObject{Rows: rows, Name: s.Name}
  405. }
  406. func (s *DbStmtObject) QueryRow(line string, args ...Object) Object {
  407. var params []interface{}
  408. for idx, arg := range args {
  409. _, ok := arg.(*String)
  410. if !ok {
  411. return NewError(line, PARAMTYPEERROR, "all", "queryRow", "*String", args[idx].Type())
  412. }
  413. params = append(params, arg.Inspect())
  414. }
  415. row := s.Stmt.QueryRow(params...)
  416. return &DbRowObject{Row: row, Name: s.Name}
  417. }
  418. //***************************************************************
  419. // DB Transaction object
  420. //***************************************************************
  421. type DbTxObject struct {
  422. Tx *sql.Tx
  423. Name string
  424. }
  425. func (t *DbTxObject) Inspect() string { return t.Name }
  426. func (t *DbTxObject) Type() ObjectType { return DBTX_OBJ }
  427. func (t *DbTxObject) CallMethod(line string, scope *Scope, method string, args ...Object) Object {
  428. switch method {
  429. case "exec":
  430. return t.Exec(line, args...)
  431. case "query":
  432. return t.Query(line, args...)
  433. case "queryRow":
  434. return t.QueryRow(line, args...)
  435. case "prepare":
  436. return t.Prepare(line, args...)
  437. case "stmt":
  438. return t.Stmt(line, args...)
  439. case "commit":
  440. return t.Commit(line, args...)
  441. case "rollback":
  442. return t.Rollback(line, args...)
  443. default:
  444. return NewError(line, NOMETHODERROR, method, t.Type())
  445. }
  446. }
  447. func (t *DbTxObject) Exec(line string, args ...Object) Object {
  448. if len(args) < 1 {
  449. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  450. }
  451. query, ok := args[0].(*String)
  452. if !ok {
  453. return NewError(line, PARAMTYPEERROR, "first", "exec", "*String", args[0].Type())
  454. }
  455. var params []interface{}
  456. if len(args) > 1 {
  457. params = handleExecParams(args[1:])
  458. if params == nil {
  459. return NewError(line, INVALIDARG)
  460. }
  461. }
  462. result, err := t.Tx.Exec(query.String, params...)
  463. if err != nil {
  464. return NewNil(err.Error())
  465. }
  466. return &DbResultObject{Result: result, Name: t.Name}
  467. }
  468. func (t *DbTxObject) Query(line string, args ...Object) Object {
  469. if len(args) < 1 {
  470. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  471. }
  472. query, ok := args[0].(*String)
  473. if !ok {
  474. return NewError(line, PARAMTYPEERROR, "first", "query", "*String", args[0].Type())
  475. }
  476. var params []interface{}
  477. arr := args[1:]
  478. for idx, arg := range arr {
  479. _, ok := arg.(*String)
  480. if !ok {
  481. return NewError(line, PARAMTYPEERROR, "remaining", "query", "*String", arr[idx].Type())
  482. }
  483. params = append(params, arg.Inspect())
  484. }
  485. rows, err := t.Tx.Query(query.String, params...)
  486. if err != nil {
  487. return NewNil(err.Error())
  488. }
  489. return &DbRowsObject{Rows: rows, Name: t.Name}
  490. }
  491. func (t *DbTxObject) QueryRow(line string, args ...Object) Object {
  492. if len(args) < 1 {
  493. return NewError(line, ARGUMENTERROR, "at least 1", len(args))
  494. }
  495. query, ok := args[0].(*String)
  496. if !ok {
  497. return NewError(line, PARAMTYPEERROR, "first", "queryRow", "*String", args[0].Type())
  498. }
  499. var params []interface{}
  500. arr := args[1:]
  501. for idx, arg := range arr {
  502. _, ok := arg.(*String)
  503. if !ok {
  504. return NewError(line, PARAMTYPEERROR, "remaining", "queryRow", "*String", arr[idx].Type())
  505. }
  506. params = append(params, arg.Inspect())
  507. }
  508. row := t.Tx.QueryRow(query.String, params...)
  509. return &DbRowObject{Row: row, Name: t.Name}
  510. }
  511. func (t *DbTxObject) Prepare(line string, args ...Object) Object {
  512. if len(args) != 1 {
  513. return NewError(line, ARGUMENTERROR, "1", len(args))
  514. }
  515. query, ok := args[0].(*String)
  516. if !ok {
  517. return NewError(line, PARAMTYPEERROR, "first", "prepare", "*String", args[0].Type())
  518. }
  519. stmt, err := t.Tx.Prepare(query.String)
  520. if err != nil {
  521. return NewNil(err.Error())
  522. }
  523. return &DbStmtObject{Stmt: stmt, Name: t.Name}
  524. }
  525. func (t *DbTxObject) Stmt(line string, args ...Object) Object {
  526. if len(args) != 1 {
  527. return NewError(line, ARGUMENTERROR, "1", len(args))
  528. }
  529. stmt, ok := args[0].(*DbStmtObject)
  530. if !ok {
  531. return NewError(line, PARAMTYPEERROR, "first", "stmt", "*DbStmtObject", args[0].Type())
  532. }
  533. newStmt := t.Tx.Stmt(stmt.Stmt)
  534. return &DbStmtObject{Stmt: newStmt, Name: t.Name}
  535. }
  536. func (t *DbTxObject) Commit(line string, args ...Object) Object {
  537. if len(args) != 0 {
  538. return NewError(line, ARGUMENTERROR, "0", len(args))
  539. }
  540. err := t.Tx.Commit()
  541. if err != nil {
  542. return NewFalseObj(err.Error())
  543. }
  544. return TRUE
  545. }
  546. func (t *DbTxObject) Rollback(line string, args ...Object) Object {
  547. if len(args) != 0 {
  548. return NewError(line, ARGUMENTERROR, "0", len(args))
  549. }
  550. err := t.Tx.Rollback()
  551. if err != nil {
  552. return NewFalseObj(err.Error())
  553. }
  554. return TRUE
  555. }
  556. //Handling `Exec`'s parameters, mainly for handling `null`
  557. //func handleExecParams(args []Object) []interface{} {
  558. //
  559. // var params []interface{}
  560. // for _, arg := range args {
  561. // switch arg.(type) {
  562. // case *String:
  563. // var nulStr sql.NullString
  564. //
  565. // s := arg.(*String)
  566. // if s.Valid {
  567. // nulStr = sql.NullString{String:s.String, Valid:true}
  568. // } else {
  569. // nulStr = sql.NullString{}
  570. // }
  571. // params = append(params, nulStr)
  572. // case *Integer:
  573. // var nulInt sql.NullInt64
  574. //
  575. // i := arg.(*Integer)
  576. // if i.Valid {
  577. // nulInt = sql.NullInt64{Int64:i.Int64, Valid:true}
  578. // } else {
  579. // nulInt = sql.NullInt64{}
  580. // }
  581. // params = append(params, nulInt)
  582. // case *Float:
  583. // var nulFloat sql.NullFloat64
  584. //
  585. // f := arg.(*Float)
  586. // if f.Valid {
  587. // nulFloat = sql.NullFloat64{Float64:f.Float64, Valid:true}
  588. // } else {
  589. // nulFloat = sql.NullFloat64{}
  590. // }
  591. // params = append(params, nulFloat)
  592. // case *Boolean:
  593. // var nulBool sql.NullBool
  594. //
  595. // b := arg.(*Boolean)
  596. // if b.Valid {
  597. // nulBool = sql.NullBool{Bool:b.Bool, Valid:true}
  598. // } else {
  599. // nulBool = sql.NullBool{}
  600. // }
  601. // params = append(params, nulBool)
  602. // default:
  603. // return nil
  604. // } //end switch
  605. // }
  606. //
  607. // return params
  608. //}
  609. //Handling `Exec`'s parameters, mainly for handling `null`
  610. func handleExecParams(args []Object) []interface{} {
  611. var params []interface{}
  612. for _, arg := range args {
  613. params = append(params, arg)
  614. }
  615. return params
  616. }
  617. func scan(rowObj interface{}, line string, args ...Object) Object {
  618. if len(args) < 1 {
  619. return NewError(line, ARGUMENTERROR, ">=1", len(args))
  620. }
  621. //Must do `[]Object ==> []interface{}`,or compiler will report error
  622. var values []interface{}
  623. for _, v := range args {
  624. switch v.(type) {
  625. case *Integer, *UInteger, *Boolean, *Float, *String, *TimeObj:
  626. values = append(values, v)
  627. default:
  628. return NewError(line, DBSCANERROR)
  629. } //end switch
  630. } //end for
  631. var err error
  632. switch rowObj.(type) {
  633. case *sql.Rows:
  634. row := rowObj.(*sql.Rows)
  635. err = row.Scan(values...)
  636. case *sql.Row:
  637. row := rowObj.(*sql.Row)
  638. err = row.Scan(values...)
  639. }
  640. if err != nil {
  641. return NewFalseObj(err.Error())
  642. }
  643. return TRUE
  644. }