statement.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. package gorm
  2. import (
  3. "context"
  4. "database/sql"
  5. "database/sql/driver"
  6. "fmt"
  7. "reflect"
  8. "sort"
  9. "strconv"
  10. "strings"
  11. "sync"
  12. "gorm.io/gorm/clause"
  13. "gorm.io/gorm/logger"
  14. "gorm.io/gorm/schema"
  15. "gorm.io/gorm/utils"
  16. )
  17. // Statement statement
  18. type Statement struct {
  19. *DB
  20. TableExpr *clause.Expr
  21. Table string
  22. Model interface{}
  23. Unscoped bool
  24. Dest interface{}
  25. ReflectValue reflect.Value
  26. Clauses map[string]clause.Clause
  27. BuildClauses []string
  28. Distinct bool
  29. Selects []string // selected columns
  30. Omits []string // omit columns
  31. Joins []join
  32. Preloads map[string][]interface{}
  33. Settings sync.Map
  34. ConnPool ConnPool
  35. Schema *schema.Schema
  36. Context context.Context
  37. RaiseErrorOnNotFound bool
  38. SkipHooks bool
  39. SQL strings.Builder
  40. Vars []interface{}
  41. CurDestIndex int
  42. attrs []interface{}
  43. assigns []interface{}
  44. scopes []func(*DB) *DB
  45. }
  46. type join struct {
  47. Name string
  48. Conds []interface{}
  49. On *clause.Where
  50. }
  51. // StatementModifier statement modifier interface
  52. type StatementModifier interface {
  53. ModifyStatement(*Statement)
  54. }
  55. // WriteString write string
  56. func (stmt *Statement) WriteString(str string) (int, error) {
  57. return stmt.SQL.WriteString(str)
  58. }
  59. // WriteByte write byte
  60. func (stmt *Statement) WriteByte(c byte) error {
  61. return stmt.SQL.WriteByte(c)
  62. }
  63. // WriteQuoted write quoted value
  64. func (stmt *Statement) WriteQuoted(value interface{}) {
  65. stmt.QuoteTo(&stmt.SQL, value)
  66. }
  67. // QuoteTo write quoted value to writer
  68. func (stmt *Statement) QuoteTo(writer clause.Writer, field interface{}) {
  69. switch v := field.(type) {
  70. case clause.Table:
  71. if v.Name == clause.CurrentTable {
  72. if stmt.TableExpr != nil {
  73. stmt.TableExpr.Build(stmt)
  74. } else {
  75. stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
  76. }
  77. } else if v.Raw {
  78. writer.WriteString(v.Name)
  79. } else {
  80. stmt.DB.Dialector.QuoteTo(writer, v.Name)
  81. }
  82. if v.Alias != "" {
  83. writer.WriteByte(' ')
  84. stmt.DB.Dialector.QuoteTo(writer, v.Alias)
  85. }
  86. case clause.Column:
  87. if v.Table != "" {
  88. if v.Table == clause.CurrentTable {
  89. stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
  90. } else {
  91. stmt.DB.Dialector.QuoteTo(writer, v.Table)
  92. }
  93. writer.WriteByte('.')
  94. }
  95. if v.Name == clause.PrimaryKey {
  96. if stmt.Schema == nil {
  97. stmt.DB.AddError(ErrModelValueRequired)
  98. } else if stmt.Schema.PrioritizedPrimaryField != nil {
  99. stmt.DB.Dialector.QuoteTo(writer, stmt.Schema.PrioritizedPrimaryField.DBName)
  100. } else if len(stmt.Schema.DBNames) > 0 {
  101. stmt.DB.Dialector.QuoteTo(writer, stmt.Schema.DBNames[0])
  102. }
  103. } else if v.Raw {
  104. writer.WriteString(v.Name)
  105. } else {
  106. stmt.DB.Dialector.QuoteTo(writer, v.Name)
  107. }
  108. if v.Alias != "" {
  109. writer.WriteString(" AS ")
  110. stmt.DB.Dialector.QuoteTo(writer, v.Alias)
  111. }
  112. case []clause.Column:
  113. writer.WriteByte('(')
  114. for idx, d := range v {
  115. if idx > 0 {
  116. writer.WriteString(",")
  117. }
  118. stmt.QuoteTo(writer, d)
  119. }
  120. writer.WriteByte(')')
  121. case clause.Expr:
  122. v.Build(stmt)
  123. case string:
  124. stmt.DB.Dialector.QuoteTo(writer, v)
  125. case []string:
  126. writer.WriteByte('(')
  127. for idx, d := range v {
  128. if idx > 0 {
  129. writer.WriteString(",")
  130. }
  131. stmt.DB.Dialector.QuoteTo(writer, d)
  132. }
  133. writer.WriteByte(')')
  134. default:
  135. stmt.DB.Dialector.QuoteTo(writer, fmt.Sprint(field))
  136. }
  137. }
  138. // Quote returns quoted value
  139. func (stmt *Statement) Quote(field interface{}) string {
  140. var builder strings.Builder
  141. stmt.QuoteTo(&builder, field)
  142. return builder.String()
  143. }
  144. // AddVar add var
  145. func (stmt *Statement) AddVar(writer clause.Writer, vars ...interface{}) {
  146. for idx, v := range vars {
  147. if idx > 0 {
  148. writer.WriteByte(',')
  149. }
  150. switch v := v.(type) {
  151. case sql.NamedArg:
  152. stmt.Vars = append(stmt.Vars, v.Value)
  153. case clause.Column, clause.Table:
  154. stmt.QuoteTo(writer, v)
  155. case Valuer:
  156. stmt.AddVar(writer, v.GormValue(stmt.Context, stmt.DB))
  157. case clause.Expr:
  158. v.Build(stmt)
  159. case *clause.Expr:
  160. v.Build(stmt)
  161. case driver.Valuer:
  162. stmt.Vars = append(stmt.Vars, v)
  163. stmt.DB.Dialector.BindVarTo(writer, stmt, v)
  164. case []byte:
  165. stmt.Vars = append(stmt.Vars, v)
  166. stmt.DB.Dialector.BindVarTo(writer, stmt, v)
  167. case []interface{}:
  168. if len(v) > 0 {
  169. writer.WriteByte('(')
  170. stmt.AddVar(writer, v...)
  171. writer.WriteByte(')')
  172. } else {
  173. writer.WriteString("(NULL)")
  174. }
  175. case *DB:
  176. subdb := v.Session(&Session{Logger: logger.Discard, DryRun: true}).getInstance()
  177. if v.Statement.SQL.Len() > 0 {
  178. var (
  179. vars = subdb.Statement.Vars
  180. sql = v.Statement.SQL.String()
  181. )
  182. subdb.Statement.Vars = make([]interface{}, 0, len(vars))
  183. for _, vv := range vars {
  184. subdb.Statement.Vars = append(subdb.Statement.Vars, vv)
  185. bindvar := strings.Builder{}
  186. v.Dialector.BindVarTo(&bindvar, subdb.Statement, vv)
  187. sql = strings.Replace(sql, bindvar.String(), "?", 1)
  188. }
  189. subdb.Statement.SQL.Reset()
  190. subdb.Statement.Vars = stmt.Vars
  191. if strings.Contains(sql, "@") {
  192. clause.NamedExpr{SQL: sql, Vars: vars}.Build(subdb.Statement)
  193. } else {
  194. clause.Expr{SQL: sql, Vars: vars}.Build(subdb.Statement)
  195. }
  196. } else {
  197. subdb.Statement.Vars = append(stmt.Vars, subdb.Statement.Vars...)
  198. subdb.callbacks.Query().Execute(subdb)
  199. }
  200. writer.WriteString(subdb.Statement.SQL.String())
  201. stmt.Vars = subdb.Statement.Vars
  202. default:
  203. switch rv := reflect.ValueOf(v); rv.Kind() {
  204. case reflect.Slice, reflect.Array:
  205. if rv.Len() == 0 {
  206. writer.WriteString("(NULL)")
  207. } else {
  208. writer.WriteByte('(')
  209. for i := 0; i < rv.Len(); i++ {
  210. if i > 0 {
  211. writer.WriteByte(',')
  212. }
  213. stmt.AddVar(writer, rv.Index(i).Interface())
  214. }
  215. writer.WriteByte(')')
  216. }
  217. default:
  218. stmt.Vars = append(stmt.Vars, v)
  219. stmt.DB.Dialector.BindVarTo(writer, stmt, v)
  220. }
  221. }
  222. }
  223. }
  224. // AddClause add clause
  225. func (stmt *Statement) AddClause(v clause.Interface) {
  226. if optimizer, ok := v.(StatementModifier); ok {
  227. optimizer.ModifyStatement(stmt)
  228. } else {
  229. name := v.Name()
  230. c := stmt.Clauses[name]
  231. c.Name = name
  232. v.MergeClause(&c)
  233. stmt.Clauses[name] = c
  234. }
  235. }
  236. // AddClauseIfNotExists add clause if not exists
  237. func (stmt *Statement) AddClauseIfNotExists(v clause.Interface) {
  238. if c, ok := stmt.Clauses[v.Name()]; !ok || c.Expression == nil {
  239. stmt.AddClause(v)
  240. }
  241. }
  242. // BuildCondition build condition
  243. func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []clause.Expression {
  244. if s, ok := query.(string); ok {
  245. // if it is a number, then treats it as primary key
  246. if _, err := strconv.Atoi(s); err != nil {
  247. if s == "" && len(args) == 0 {
  248. return nil
  249. } else if len(args) == 0 || (len(args) > 0 && strings.Contains(s, "?")) {
  250. // looks like a where condition
  251. return []clause.Expression{clause.Expr{SQL: s, Vars: args}}
  252. } else if len(args) > 0 && strings.Contains(s, "@") {
  253. // looks like a named query
  254. return []clause.Expression{clause.NamedExpr{SQL: s, Vars: args}}
  255. } else if len(args) == 1 {
  256. return []clause.Expression{clause.Eq{Column: s, Value: args[0]}}
  257. }
  258. }
  259. }
  260. conds := make([]clause.Expression, 0, 4)
  261. args = append([]interface{}{query}, args...)
  262. for idx, arg := range args {
  263. if valuer, ok := arg.(driver.Valuer); ok {
  264. arg, _ = valuer.Value()
  265. }
  266. switch v := arg.(type) {
  267. case clause.Expression:
  268. conds = append(conds, v)
  269. case *DB:
  270. if cs, ok := v.Statement.Clauses["WHERE"]; ok {
  271. if where, ok := cs.Expression.(clause.Where); ok {
  272. if len(where.Exprs) == 1 {
  273. if orConds, ok := where.Exprs[0].(clause.OrConditions); ok {
  274. where.Exprs[0] = clause.AndConditions(orConds)
  275. }
  276. }
  277. conds = append(conds, clause.And(where.Exprs...))
  278. } else if cs.Expression != nil {
  279. conds = append(conds, cs.Expression)
  280. }
  281. }
  282. case map[interface{}]interface{}:
  283. for i, j := range v {
  284. conds = append(conds, clause.Eq{Column: i, Value: j})
  285. }
  286. case map[string]string:
  287. var keys = make([]string, 0, len(v))
  288. for i := range v {
  289. keys = append(keys, i)
  290. }
  291. sort.Strings(keys)
  292. for _, key := range keys {
  293. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  294. }
  295. case map[string]interface{}:
  296. var keys = make([]string, 0, len(v))
  297. for i := range v {
  298. keys = append(keys, i)
  299. }
  300. sort.Strings(keys)
  301. for _, key := range keys {
  302. reflectValue := reflect.Indirect(reflect.ValueOf(v[key]))
  303. switch reflectValue.Kind() {
  304. case reflect.Slice, reflect.Array:
  305. if _, ok := v[key].(driver.Valuer); ok {
  306. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  307. } else if _, ok := v[key].(Valuer); ok {
  308. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  309. } else {
  310. // optimize reflect value length
  311. valueLen := reflectValue.Len()
  312. values := make([]interface{}, valueLen)
  313. for i := 0; i < valueLen; i++ {
  314. values[i] = reflectValue.Index(i).Interface()
  315. }
  316. conds = append(conds, clause.IN{Column: key, Values: values})
  317. }
  318. default:
  319. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  320. }
  321. }
  322. default:
  323. reflectValue := reflect.Indirect(reflect.ValueOf(arg))
  324. for reflectValue.Kind() == reflect.Ptr {
  325. reflectValue = reflectValue.Elem()
  326. }
  327. if s, err := schema.Parse(arg, stmt.DB.cacheStore, stmt.DB.NamingStrategy); err == nil {
  328. selectedColumns := map[string]bool{}
  329. if idx == 0 {
  330. for _, v := range args[1:] {
  331. if vs, ok := v.(string); ok {
  332. selectedColumns[vs] = true
  333. }
  334. }
  335. }
  336. restricted := len(selectedColumns) != 0
  337. switch reflectValue.Kind() {
  338. case reflect.Struct:
  339. for _, field := range s.Fields {
  340. selected := selectedColumns[field.DBName] || selectedColumns[field.Name]
  341. if selected || (!restricted && field.Readable) {
  342. if v, isZero := field.ValueOf(reflectValue); !isZero || selected {
  343. if field.DBName != "" {
  344. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.DBName}, Value: v})
  345. } else if field.DataType != "" {
  346. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.Name}, Value: v})
  347. }
  348. }
  349. }
  350. }
  351. case reflect.Slice, reflect.Array:
  352. for i := 0; i < reflectValue.Len(); i++ {
  353. for _, field := range s.Fields {
  354. selected := selectedColumns[field.DBName] || selectedColumns[field.Name]
  355. if selected || (!restricted && field.Readable) {
  356. if v, isZero := field.ValueOf(reflectValue.Index(i)); !isZero || selected {
  357. if field.DBName != "" {
  358. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.DBName}, Value: v})
  359. } else if field.DataType != "" {
  360. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.Name}, Value: v})
  361. }
  362. }
  363. }
  364. }
  365. }
  366. }
  367. if restricted {
  368. break
  369. }
  370. } else if !reflectValue.IsValid() {
  371. stmt.AddError(ErrInvalidData)
  372. } else if len(conds) == 0 {
  373. if len(args) == 1 {
  374. switch reflectValue.Kind() {
  375. case reflect.Slice, reflect.Array:
  376. // optimize reflect value length
  377. valueLen := reflectValue.Len()
  378. values := make([]interface{}, valueLen)
  379. for i := 0; i < valueLen; i++ {
  380. values[i] = reflectValue.Index(i).Interface()
  381. }
  382. if len(values) > 0 {
  383. conds = append(conds, clause.IN{Column: clause.PrimaryColumn, Values: values})
  384. }
  385. return conds
  386. }
  387. }
  388. conds = append(conds, clause.IN{Column: clause.PrimaryColumn, Values: args})
  389. }
  390. }
  391. }
  392. return conds
  393. }
  394. // Build build sql with clauses names
  395. func (stmt *Statement) Build(clauses ...string) {
  396. var firstClauseWritten bool
  397. for _, name := range clauses {
  398. if c, ok := stmt.Clauses[name]; ok {
  399. if firstClauseWritten {
  400. stmt.WriteByte(' ')
  401. }
  402. firstClauseWritten = true
  403. if b, ok := stmt.DB.ClauseBuilders[name]; ok {
  404. b(c, stmt)
  405. } else {
  406. c.Build(stmt)
  407. }
  408. }
  409. }
  410. }
  411. func (stmt *Statement) Parse(value interface{}) (err error) {
  412. if stmt.Schema, err = schema.Parse(value, stmt.DB.cacheStore, stmt.DB.NamingStrategy); err == nil && stmt.Table == "" {
  413. if tables := strings.Split(stmt.Schema.Table, "."); len(tables) == 2 {
  414. stmt.TableExpr = &clause.Expr{SQL: stmt.Quote(stmt.Schema.Table)}
  415. stmt.Table = tables[1]
  416. return
  417. }
  418. stmt.Table = stmt.Schema.Table
  419. }
  420. return err
  421. }
  422. func (stmt *Statement) clone() *Statement {
  423. newStmt := &Statement{
  424. TableExpr: stmt.TableExpr,
  425. Table: stmt.Table,
  426. Model: stmt.Model,
  427. Unscoped: stmt.Unscoped,
  428. Dest: stmt.Dest,
  429. ReflectValue: stmt.ReflectValue,
  430. Clauses: map[string]clause.Clause{},
  431. Distinct: stmt.Distinct,
  432. Selects: stmt.Selects,
  433. Omits: stmt.Omits,
  434. Preloads: map[string][]interface{}{},
  435. ConnPool: stmt.ConnPool,
  436. Schema: stmt.Schema,
  437. Context: stmt.Context,
  438. RaiseErrorOnNotFound: stmt.RaiseErrorOnNotFound,
  439. SkipHooks: stmt.SkipHooks,
  440. }
  441. if stmt.SQL.Len() > 0 {
  442. newStmt.SQL.WriteString(stmt.SQL.String())
  443. newStmt.Vars = make([]interface{}, 0, len(stmt.Vars))
  444. newStmt.Vars = append(newStmt.Vars, stmt.Vars...)
  445. }
  446. for k, c := range stmt.Clauses {
  447. newStmt.Clauses[k] = c
  448. }
  449. for k, p := range stmt.Preloads {
  450. newStmt.Preloads[k] = p
  451. }
  452. if len(stmt.Joins) > 0 {
  453. newStmt.Joins = make([]join, len(stmt.Joins))
  454. copy(newStmt.Joins, stmt.Joins)
  455. }
  456. if len(stmt.scopes) > 0 {
  457. newStmt.scopes = make([]func(*DB) *DB, len(stmt.scopes))
  458. copy(newStmt.scopes, stmt.scopes)
  459. }
  460. stmt.Settings.Range(func(k, v interface{}) bool {
  461. newStmt.Settings.Store(k, v)
  462. return true
  463. })
  464. return newStmt
  465. }
  466. // SetColumn set column's value
  467. // stmt.SetColumn("Name", "jinzhu") // Hooks Method
  468. // stmt.SetColumn("Name", "jinzhu", true) // Callbacks Method
  469. func (stmt *Statement) SetColumn(name string, value interface{}, fromCallbacks ...bool) {
  470. if v, ok := stmt.Dest.(map[string]interface{}); ok {
  471. v[name] = value
  472. } else if v, ok := stmt.Dest.([]map[string]interface{}); ok {
  473. for _, m := range v {
  474. m[name] = value
  475. }
  476. } else if stmt.Schema != nil {
  477. if field := stmt.Schema.LookUpField(name); field != nil {
  478. destValue := reflect.ValueOf(stmt.Dest)
  479. for destValue.Kind() == reflect.Ptr {
  480. destValue = destValue.Elem()
  481. }
  482. if stmt.ReflectValue != destValue {
  483. if !destValue.CanAddr() {
  484. destValueCanAddr := reflect.New(destValue.Type())
  485. destValueCanAddr.Elem().Set(destValue)
  486. stmt.Dest = destValueCanAddr.Interface()
  487. destValue = destValueCanAddr.Elem()
  488. }
  489. switch destValue.Kind() {
  490. case reflect.Struct:
  491. field.Set(destValue, value)
  492. default:
  493. stmt.AddError(ErrInvalidData)
  494. }
  495. }
  496. switch stmt.ReflectValue.Kind() {
  497. case reflect.Slice, reflect.Array:
  498. if len(fromCallbacks) > 0 {
  499. for i := 0; i < stmt.ReflectValue.Len(); i++ {
  500. field.Set(stmt.ReflectValue.Index(i), value)
  501. }
  502. } else {
  503. field.Set(stmt.ReflectValue.Index(stmt.CurDestIndex), value)
  504. }
  505. case reflect.Struct:
  506. if !stmt.ReflectValue.CanAddr() {
  507. stmt.AddError(ErrInvalidValue)
  508. return
  509. }
  510. field.Set(stmt.ReflectValue, value)
  511. }
  512. } else {
  513. stmt.AddError(ErrInvalidField)
  514. }
  515. } else {
  516. stmt.AddError(ErrInvalidField)
  517. }
  518. }
  519. // Changed check model changed or not when updating
  520. func (stmt *Statement) Changed(fields ...string) bool {
  521. modelValue := stmt.ReflectValue
  522. switch modelValue.Kind() {
  523. case reflect.Slice, reflect.Array:
  524. modelValue = stmt.ReflectValue.Index(stmt.CurDestIndex)
  525. }
  526. selectColumns, restricted := stmt.SelectAndOmitColumns(false, true)
  527. changed := func(field *schema.Field) bool {
  528. fieldValue, _ := field.ValueOf(modelValue)
  529. if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) {
  530. if v, ok := stmt.Dest.(map[string]interface{}); ok {
  531. if fv, ok := v[field.Name]; ok {
  532. return !utils.AssertEqual(fv, fieldValue)
  533. } else if fv, ok := v[field.DBName]; ok {
  534. return !utils.AssertEqual(fv, fieldValue)
  535. }
  536. } else {
  537. destValue := reflect.ValueOf(stmt.Dest)
  538. for destValue.Kind() == reflect.Ptr {
  539. destValue = destValue.Elem()
  540. }
  541. changedValue, zero := field.ValueOf(destValue)
  542. return !zero && !utils.AssertEqual(changedValue, fieldValue)
  543. }
  544. }
  545. return false
  546. }
  547. if len(fields) == 0 {
  548. for _, field := range stmt.Schema.FieldsByDBName {
  549. if changed(field) {
  550. return true
  551. }
  552. }
  553. } else {
  554. for _, name := range fields {
  555. if field := stmt.Schema.LookUpField(name); field != nil {
  556. if changed(field) {
  557. return true
  558. }
  559. }
  560. }
  561. }
  562. return false
  563. }
  564. // SelectAndOmitColumns get select and omit columns, select -> true, omit -> false
  565. func (stmt *Statement) SelectAndOmitColumns(requireCreate, requireUpdate bool) (map[string]bool, bool) {
  566. results := map[string]bool{}
  567. notRestricted := false
  568. // select columns
  569. for _, column := range stmt.Selects {
  570. if stmt.Schema == nil {
  571. results[column] = true
  572. } else if column == "*" {
  573. notRestricted = true
  574. for _, dbName := range stmt.Schema.DBNames {
  575. results[dbName] = true
  576. }
  577. } else if column == clause.Associations {
  578. for _, rel := range stmt.Schema.Relationships.Relations {
  579. results[rel.Name] = true
  580. }
  581. } else if field := stmt.Schema.LookUpField(column); field != nil && field.DBName != "" {
  582. results[field.DBName] = true
  583. } else {
  584. results[column] = true
  585. }
  586. }
  587. // omit columns
  588. for _, omit := range stmt.Omits {
  589. if stmt.Schema == nil {
  590. results[omit] = false
  591. } else if omit == clause.Associations {
  592. for _, rel := range stmt.Schema.Relationships.Relations {
  593. results[rel.Name] = false
  594. }
  595. } else if field := stmt.Schema.LookUpField(omit); field != nil && field.DBName != "" {
  596. results[field.DBName] = false
  597. } else {
  598. results[omit] = false
  599. }
  600. }
  601. if stmt.Schema != nil {
  602. for _, field := range stmt.Schema.FieldsByName {
  603. name := field.DBName
  604. if name == "" {
  605. name = field.Name
  606. }
  607. if requireCreate && !field.Creatable {
  608. results[name] = false
  609. } else if requireUpdate && !field.Updatable {
  610. results[name] = false
  611. }
  612. }
  613. }
  614. return results, !notRestricted && len(stmt.Selects) > 0
  615. }