github.com/runner-mei/ql@v1.1.0/stmt.go (about)

     1  // Copyright (c) 2014 ql Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ql
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/cznic/strutil"
    13  )
    14  
    15  // NOTE: all stmt implementations must be safe for concurrent use by multiple
    16  // goroutines.  If the exec method requires any execution domain local data,
    17  // they must be held out of the implementing instance.
    18  var (
    19  	_ stmt = (*alterTableAddStmt)(nil)
    20  	_ stmt = (*alterTableDropColumnStmt)(nil)
    21  	_ stmt = (*createIndexStmt)(nil)
    22  	_ stmt = (*createTableStmt)(nil)
    23  	_ stmt = (*deleteStmt)(nil) //TODO optimizer plan
    24  	_ stmt = (*dropIndexStmt)(nil)
    25  	_ stmt = (*dropTableStmt)(nil)
    26  	_ stmt = (*explainStmt)(nil)
    27  	_ stmt = (*insertIntoStmt)(nil)
    28  	_ stmt = (*selectStmt)(nil)
    29  	_ stmt = (*truncateTableStmt)(nil)
    30  	_ stmt = (*updateStmt)(nil) //TODO optimizer plan
    31  	_ stmt = beginTransactionStmt{}
    32  	_ stmt = commitStmt{}
    33  	_ stmt = rollbackStmt{}
    34  )
    35  
    36  var (
    37  	createColumn2 = mustCompile(`
    38  		create table if not exists __Column2 (
    39  			TableName string,
    40  			Name string,
    41  			NotNull bool,
    42  			ConstraintExpr string,
    43  			DefaultExpr string,
    44  		);
    45  		create index if not exists __Column2TableName on __Column2(TableName);
    46  	`)
    47  
    48  	insertColumn2 = mustCompile(`insert into __Column2 values($1, $2, $3, $4, $5)`)
    49  
    50  	selectColumn2 = MustCompile(`
    51  		select Name, NotNull, ConstraintExpr, DefaultExpr
    52  		from __Column2
    53  		where TableName == $1
    54  	`)
    55  
    56  	deleteColumn2 = mustCompile(`
    57  		delete from __Column2
    58  		where TableName == $1 && Name == $2
    59  	`)
    60  
    61  	createIndex2 = mustCompile(`
    62  		// Index register 2.
    63  		create table if not exists __Index2(
    64  			TableName string,
    65  			IndexName string,
    66  			IsUnique  bool,
    67  			IsSimple  bool,   // Just a column name or id().
    68  			Root      int64,  // BTree handle
    69  		);
    70  
    71  		// Expressions for given index. Compared in order of id(__Index2_Expr).
    72  		create table if not exists __Index2_Expr(
    73  			Index2_ID int,
    74  			Expr      string,
    75  		);
    76  
    77  		create index if not exists __xIndex2_TableName on __Index2(TableName);
    78  		create unique index if not exists __xIndex2_IndexName on __Index2(IndexName);
    79  		create index if not exists __xIndex2_ID on __Index2(id());
    80  		create index if not exists __xIndex2_Expr_Index2_ID on __Index2_Expr(Index2_ID);
    81  `)
    82  
    83  	insertIndex2     = mustCompile("insert into __Index2 values($1, $2, $3, $4, $5)")
    84  	insertIndex2Expr = mustCompile("insert into __Index2_Expr values($1, $2)")
    85  
    86  	deleteIndex2ByIndexName = mustCompile(`
    87  		delete from __Index2_Expr
    88  		where Index2_ID in (
    89  			select id() from __Index2 where IndexName == $1;
    90  		);	
    91  
    92  		delete from __Index2
    93  		where IndexName == $1;
    94  `)
    95  	deleteIndex2ByTableName = mustCompile(`
    96  		delete from __Index2_Expr
    97  		where Index2_ID in (
    98  			select id() from __Index2 where TableName == $1;
    99  		);	
   100  
   101  		delete from __Index2
   102  		where TableName == $1;
   103  `)
   104  )
   105  
   106  type stmt interface {
   107  	// never invoked for
   108  	// - beginTransactionStmt
   109  	// - commitStmt
   110  	// - rollbackStmt
   111  	exec(ctx *execCtx) (Recordset, error)
   112  
   113  	explain(ctx *execCtx, w strutil.Formatter)
   114  
   115  	// return value ignored for
   116  	// - beginTransactionStmt
   117  	// - commitStmt
   118  	// - rollbackStmt
   119  	isUpdating() bool
   120  	String() string
   121  }
   122  
   123  type execCtx struct { //LATER +shared temp
   124  	db  *DB
   125  	arg []interface{}
   126  }
   127  
   128  type explainStmt struct {
   129  	s stmt
   130  }
   131  
   132  func (s *explainStmt) explain(ctx *execCtx, w strutil.Formatter) {
   133  	for {
   134  		x, ok := s.s.(*explainStmt)
   135  		if !ok {
   136  			s.s.explain(ctx, w)
   137  			return
   138  		}
   139  
   140  		s = x
   141  	}
   142  }
   143  
   144  func (s *explainStmt) String() string {
   145  	return "EXPLAIN " + s.s.String()
   146  }
   147  
   148  func (*explainStmt) isUpdating() bool { return false }
   149  
   150  func (s *explainStmt) exec(ctx *execCtx) (_ Recordset, err error) {
   151  	return recordset{ctx, &explainDefaultPlan{s.s}, ctx.db.cc}, nil
   152  }
   153  
   154  type updateStmt struct {
   155  	tableName string
   156  	list      []assignment
   157  	where     expression
   158  }
   159  
   160  func (s *updateStmt) explain(ctx *execCtx, w strutil.Formatter) {
   161  	w.Format("%s\n", s)
   162  }
   163  
   164  func (s *updateStmt) String() string {
   165  	u := fmt.Sprintf("UPDATE %s", s.tableName)
   166  	a := make([]string, len(s.list))
   167  	for i, v := range s.list {
   168  		a[i] = v.String()
   169  	}
   170  	w := ""
   171  	if s.where != nil {
   172  		w = fmt.Sprintf(" WHERE %s", s.where)
   173  	}
   174  	return fmt.Sprintf("%s %s%s;", u, strings.Join(a, ", "), w)
   175  }
   176  
   177  func (s *updateStmt) exec(ctx *execCtx) (_ Recordset, err error) {
   178  	t, ok := ctx.db.root.tables[s.tableName]
   179  	if !ok {
   180  		return nil, fmt.Errorf("UPDATE: table %s does not exist", s.tableName)
   181  	}
   182  
   183  	tcols := make([]*col, len(s.list))
   184  	for i, asgn := range s.list {
   185  		col := findCol(t.cols, asgn.colName)
   186  		if col == nil {
   187  			return nil, fmt.Errorf("UPDATE: unknown column %s", asgn.colName)
   188  		}
   189  		tcols[i] = col
   190  	}
   191  
   192  	m := map[interface{}]interface{}{}
   193  	var nh int64
   194  	expr := s.where
   195  	blobCols := t.blobCols()
   196  	cc := ctx.db.cc
   197  	var old []interface{}
   198  	var touched []bool
   199  	if t.hasIndices() {
   200  		old = make([]interface{}, len(t.cols0))
   201  		touched = make([]bool, len(t.cols0))
   202  	}
   203  	for h := t.head; h != 0; h = nh {
   204  		// Read can return lazily expanded chunks
   205  		data, err := t.store.Read(nil, h, t.cols...)
   206  		if err != nil {
   207  			return nil, err
   208  		}
   209  
   210  		nh = data[0].(int64)
   211  		for _, col := range t.cols {
   212  			m[col.name] = data[2+col.index]
   213  		}
   214  		id := data[1].(int64)
   215  		m["$id"] = id
   216  		if expr != nil {
   217  			val, err := s.where.eval(ctx, m)
   218  			if err != nil {
   219  				return nil, err
   220  			}
   221  
   222  			if val == nil {
   223  				continue
   224  			}
   225  
   226  			x, ok := val.(bool)
   227  			if !ok {
   228  				return nil, fmt.Errorf("invalid WHERE expression %s (value of type %T)", val, val)
   229  			}
   230  
   231  			if !x {
   232  				continue
   233  			}
   234  		}
   235  
   236  		// hit
   237  		for _, ix := range t.indices2 {
   238  			vlist, err := ix.eval(ctx, t.cols, id, data[2:])
   239  			if err != nil {
   240  				return nil, err
   241  			}
   242  
   243  			if err := ix.x.Delete(vlist, h); err != nil {
   244  				return nil, err
   245  			}
   246  		}
   247  		for i, asgn := range s.list {
   248  			val, err := asgn.expr.eval(ctx, m)
   249  			if err != nil {
   250  				return nil, err
   251  			}
   252  
   253  			colIndex := tcols[i].index
   254  			if t.hasIndices() {
   255  				old[colIndex] = data[2+colIndex]
   256  				touched[colIndex] = true
   257  			}
   258  			data[2+colIndex] = val
   259  		}
   260  		if err = typeCheck(data[2:], t.cols); err != nil {
   261  			return nil, err
   262  		}
   263  
   264  		if err = t.checkConstraintsAndDefaults(ctx, data[2:], m); err != nil {
   265  			return nil, err
   266  		}
   267  
   268  		for i, v := range t.indices {
   269  			if i == 0 { // id() N/A
   270  				continue
   271  			}
   272  
   273  			if v == nil || !touched[i-1] {
   274  				continue
   275  			}
   276  
   277  			if err = v.x.Delete([]interface{}{old[i-1]}, h); err != nil {
   278  				return nil, err
   279  			}
   280  		}
   281  
   282  		if err = t.store.UpdateRow(h, blobCols, data...); err != nil { //LATER detect which blobs are actually affected
   283  			return nil, err
   284  		}
   285  
   286  		for i, v := range t.indices {
   287  			if i == 0 { // id() N/A
   288  				continue
   289  			}
   290  
   291  			if v == nil || !touched[i-1] {
   292  				continue
   293  			}
   294  
   295  			if err = v.x.Create([]interface{}{data[2+i-1]}, h); err != nil {
   296  				return nil, err
   297  			}
   298  		}
   299  		for _, ix := range t.indices2 {
   300  			vlist, err := ix.eval(ctx, t.cols, id, data[2:])
   301  			if err != nil {
   302  				return nil, err
   303  			}
   304  
   305  			if err := ix.x.Create(vlist, h); err != nil {
   306  				return nil, err
   307  			}
   308  		}
   309  
   310  		cc.RowsAffected++
   311  	}
   312  	return
   313  }
   314  
   315  func (s *updateStmt) isUpdating() bool { return true }
   316  
   317  type deleteStmt struct {
   318  	tableName string
   319  	where     expression
   320  }
   321  
   322  func (s *deleteStmt) explain(ctx *execCtx, w strutil.Formatter) {
   323  	w.Format("%s\n", s)
   324  }
   325  
   326  func (s *deleteStmt) String() string {
   327  	switch {
   328  	case s.where == nil:
   329  		return fmt.Sprintf("DELETE FROM %s;", s.tableName)
   330  	default:
   331  		return fmt.Sprintf("DELETE FROM %s WHERE %s;", s.tableName, s.where)
   332  	}
   333  }
   334  
   335  func (s *deleteStmt) exec(ctx *execCtx) (_ Recordset, err error) {
   336  	t, ok := ctx.db.root.tables[s.tableName]
   337  	if !ok {
   338  		return nil, fmt.Errorf("DELETE FROM: table %s does not exist", s.tableName)
   339  	}
   340  
   341  	m := map[interface{}]interface{}{}
   342  	var ph, h, nh int64
   343  	var data []interface{}
   344  	blobCols := t.blobCols()
   345  	cc := ctx.db.cc
   346  	for h = t.head; h != 0; ph, h = h, nh {
   347  		for i, v := range data {
   348  			c, ok := v.(chunk)
   349  			if !ok {
   350  				continue
   351  			}
   352  
   353  			data[i] = c.b
   354  		}
   355  		// Read can return lazily expanded chunks
   356  		data, err = t.store.Read(nil, h, t.cols...)
   357  		if err != nil {
   358  			return nil, err
   359  		}
   360  
   361  		nh = data[0].(int64)
   362  		for _, col := range t.cols {
   363  			m[col.name] = data[2+col.index]
   364  		}
   365  		id := data[1].(int64)
   366  		m["$id"] = id
   367  		val, err := s.where.eval(ctx, m)
   368  		if err != nil {
   369  			return nil, err
   370  		}
   371  
   372  		if val == nil {
   373  			continue
   374  		}
   375  
   376  		x, ok := val.(bool)
   377  		if !ok {
   378  			return nil, fmt.Errorf("invalid WHERE expression %s (value of type %T)", val, val)
   379  		}
   380  
   381  		if !x {
   382  			continue
   383  		}
   384  
   385  		// hit
   386  		for i, v := range t.indices {
   387  			if v == nil {
   388  				continue
   389  			}
   390  
   391  			// overflow chunks left in place
   392  			if err = v.x.Delete([]interface{}{data[i+1]}, h); err != nil {
   393  				return nil, err
   394  			}
   395  		}
   396  		for _, ix := range t.indices2 {
   397  			vlist, err := ix.eval(ctx, t.cols, id, data[2:])
   398  			if err != nil {
   399  				return nil, err
   400  			}
   401  
   402  			if err := ix.x.Delete(vlist, h); err != nil {
   403  				return nil, err
   404  			}
   405  		}
   406  
   407  		// overflow chunks freed here
   408  		if err = t.store.Delete(h, blobCols...); err != nil {
   409  			return nil, err
   410  		}
   411  
   412  		cc.RowsAffected++
   413  		switch {
   414  		case ph == 0 && nh == 0: // "only"
   415  			fallthrough
   416  		case ph == 0 && nh != 0: // "first"
   417  			if err = t.store.Update(t.hhead, nh); err != nil {
   418  				return nil, err
   419  			}
   420  
   421  			t.head, h = nh, 0
   422  		case ph != 0 && nh == 0: // "last"
   423  			fallthrough
   424  		case ph != 0 && nh != 0: // "inner"
   425  			pdata, err := t.store.Read(nil, ph, t.cols...)
   426  			if err != nil {
   427  				return nil, err
   428  			}
   429  
   430  			for i, v := range pdata {
   431  				if x, ok := v.(chunk); ok {
   432  					pdata[i] = x.b
   433  				}
   434  			}
   435  			pdata[0] = nh
   436  			if err = t.store.Update(ph, pdata...); err != nil {
   437  				return nil, err
   438  			}
   439  
   440  			h = ph
   441  		}
   442  	}
   443  
   444  	return
   445  }
   446  
   447  func (s *deleteStmt) isUpdating() bool { return true }
   448  
   449  type truncateTableStmt struct {
   450  	tableName string
   451  }
   452  
   453  func (s *truncateTableStmt) explain(ctx *execCtx, w strutil.Formatter) {
   454  	w.Format("%s\n", s)
   455  }
   456  
   457  func (s *truncateTableStmt) String() string { return fmt.Sprintf("TRUNCATE TABLE %s;", s.tableName) }
   458  
   459  func (s *truncateTableStmt) exec(ctx *execCtx) (Recordset, error) {
   460  	t, ok := ctx.db.root.tables[s.tableName]
   461  	if !ok {
   462  		return nil, fmt.Errorf("TRUNCATE TABLE: table %s does not exist", s.tableName)
   463  	}
   464  
   465  	return nil, t.truncate()
   466  }
   467  
   468  func (s *truncateTableStmt) isUpdating() bool { return true }
   469  
   470  type dropIndexStmt struct {
   471  	ifExists  bool
   472  	indexName string
   473  }
   474  
   475  func (s *dropIndexStmt) explain(ctx *execCtx, w strutil.Formatter) {
   476  	w.Format("%s\n", s)
   477  }
   478  
   479  func (s *dropIndexStmt) String() string { return fmt.Sprintf("DROP INDEX %s;", s.indexName) }
   480  
   481  func (s *dropIndexStmt) exec(ctx *execCtx) (Recordset, error) {
   482  	t, x := ctx.db.root.findIndexByName(s.indexName)
   483  	if x == nil {
   484  		if s.ifExists {
   485  			return nil, nil
   486  		}
   487  
   488  		return nil, fmt.Errorf("DROP INDEX: index %s does not exist", s.indexName)
   489  	}
   490  
   491  	if ctx.db.hasAllIndex2() {
   492  		if err := ctx.db.deleteIndex2ByIndexName(s.indexName); err != nil {
   493  			return nil, err
   494  		}
   495  	}
   496  
   497  	switch ix := x.(type) {
   498  	case *indexedCol:
   499  		for i, v := range t.indices {
   500  			if v == nil || v.name != s.indexName {
   501  				continue
   502  			}
   503  
   504  			return nil, t.dropIndex(i)
   505  		}
   506  	case *index2:
   507  		delete(t.indices2, s.indexName)
   508  		return nil, ix.x.Drop()
   509  	}
   510  
   511  	panic("internal error 058")
   512  }
   513  
   514  func (s *dropIndexStmt) isUpdating() bool { return true }
   515  
   516  type dropTableStmt struct {
   517  	ifExists  bool
   518  	tableName string
   519  }
   520  
   521  func (s *dropTableStmt) explain(ctx *execCtx, w strutil.Formatter) {
   522  	w.Format("%s\n", s)
   523  }
   524  
   525  func (s *dropTableStmt) String() string { return fmt.Sprintf("DROP TABLE %s;", s.tableName) }
   526  
   527  func (s *dropTableStmt) exec(ctx *execCtx) (Recordset, error) {
   528  	t, ok := ctx.db.root.tables[s.tableName]
   529  	if !ok {
   530  		if s.ifExists {
   531  			return nil, nil
   532  		}
   533  
   534  		return nil, fmt.Errorf("DROP TABLE: table %s does not exist", s.tableName)
   535  	}
   536  
   537  	if ctx.db.hasAllIndex2() {
   538  		if err := ctx.db.deleteIndex2ByTableName(s.tableName); err != nil {
   539  			return nil, err
   540  		}
   541  	}
   542  
   543  	return nil, ctx.db.root.dropTable(t)
   544  }
   545  
   546  func (s *dropTableStmt) isUpdating() bool { return true }
   547  
   548  type alterTableDropColumnStmt struct {
   549  	tableName, colName string
   550  }
   551  
   552  func (s *alterTableDropColumnStmt) explain(ctx *execCtx, w strutil.Formatter) {
   553  	w.Format("%s\n", s)
   554  }
   555  
   556  func (s *alterTableDropColumnStmt) String() string {
   557  	return fmt.Sprintf("ALTER TABLE %s DROP COLUMN %s;", s.tableName, s.colName)
   558  }
   559  
   560  func (s *alterTableDropColumnStmt) exec(ctx *execCtx) (Recordset, error) {
   561  	t, ok := ctx.db.root.tables[s.tableName]
   562  	if !ok {
   563  		return nil, fmt.Errorf("ALTER TABLE: table %s does not exist", s.tableName)
   564  	}
   565  
   566  	cols := t.cols
   567  	for _, c := range cols {
   568  		if c.name == s.colName {
   569  			if len(cols) == 1 {
   570  				return nil, fmt.Errorf("ALTER TABLE %s DROP COLUMN: cannot drop the only column: %s", s.tableName, s.colName)
   571  			}
   572  
   573  			if _, ok := ctx.db.root.tables["__Column2"]; ok {
   574  				if _, err := deleteColumn2.l[0].exec(&execCtx{db: ctx.db, arg: []interface{}{s.tableName, c.name}}); err != nil {
   575  					return nil, err
   576  				}
   577  			}
   578  
   579  			c.name = ""
   580  			t.cols0[c.index].name = ""
   581  			if t.hasIndices() {
   582  				if len(t.indices) != 0 {
   583  					if v := t.indices[c.index+1]; v != nil {
   584  						if err := t.dropIndex(c.index + 1); err != nil {
   585  							return nil, err
   586  						}
   587  
   588  						if ctx.db.hasAllIndex2() {
   589  							if err := ctx.db.deleteIndex2ByIndexName(v.name); err != nil {
   590  								return nil, err
   591  							}
   592  						}
   593  					}
   594  				}
   595  
   596  				for nm, ix := range t.indices2 {
   597  					for _, e := range ix.exprList {
   598  						m := mentionedColumns(e)
   599  						if _, ok := m[s.colName]; ok {
   600  							if err := ctx.db.deleteIndex2ByIndexName(nm); err != nil {
   601  								return nil, err
   602  							}
   603  
   604  							if err := ix.x.Drop(); err != nil {
   605  								return nil, err
   606  							}
   607  
   608  							delete(t.indices2, nm)
   609  							break
   610  						}
   611  					}
   612  				}
   613  			}
   614  			if err := t.constraintsAndDefaults(ctx); err != nil {
   615  				return nil, err
   616  			}
   617  
   618  			return nil, t.updated()
   619  		}
   620  	}
   621  
   622  	return nil, fmt.Errorf("ALTER TABLE %s DROP COLUMN: column %s does not exist", s.tableName, s.colName)
   623  }
   624  
   625  func (s *alterTableDropColumnStmt) isUpdating() bool { return true }
   626  
   627  type alterTableAddStmt struct {
   628  	tableName string
   629  	c         *col
   630  }
   631  
   632  func (s *alterTableAddStmt) explain(ctx *execCtx, w strutil.Formatter) {
   633  	w.Format("%s\n", s)
   634  }
   635  
   636  func (s *alterTableAddStmt) String() string {
   637  	r := fmt.Sprintf("ALTER TABLE %s ADD %s %s", s.tableName, s.c.name, typeStr(s.c.typ))
   638  	c := s.c
   639  	if x := c.constraint; x != nil { //TODO add (*col).String()
   640  		switch e := x.expr; {
   641  		case e != nil:
   642  			r += " " + e.String()
   643  		default:
   644  			r += " NOT NULL"
   645  		}
   646  	}
   647  	if x := c.dflt; x != nil {
   648  		r += " DEFAULT " + x.String()
   649  	}
   650  	return r + ";"
   651  }
   652  
   653  func (s *alterTableAddStmt) exec(ctx *execCtx) (Recordset, error) {
   654  	t, ok := ctx.db.root.tables[s.tableName]
   655  	if !ok {
   656  		return nil, fmt.Errorf("ALTER TABLE: table %s does not exist", s.tableName)
   657  	}
   658  
   659  	hasRecords := t.head != 0
   660  	c := s.c
   661  	if c.constraint != nil && hasRecords {
   662  		return nil, fmt.Errorf("ALTER TABLE %s ADD %s: cannot add constrained column to table with existing data", s.tableName, c.name)
   663  	}
   664  
   665  	cols := t.cols
   666  	for _, c := range cols {
   667  		nm := c.name
   668  		if nm == s.c.name {
   669  			return nil, fmt.Errorf("ALTER TABLE %s ADD: column %s exists", s.tableName, nm)
   670  		}
   671  	}
   672  
   673  	if len(t.indices) != 0 {
   674  		t.indices = append(t.indices, nil)
   675  		t.xroots = append(t.xroots, 0)
   676  		if err := t.store.Update(t.hxroots, t.xroots...); err != nil {
   677  			return nil, err
   678  		}
   679  	}
   680  
   681  	if c.constraint != nil || c.dflt != nil {
   682  		for _, s := range createColumn2.l {
   683  			_, err := s.exec(&execCtx{db: ctx.db})
   684  			if err != nil {
   685  				return nil, err
   686  			}
   687  		}
   688  		notNull := c.constraint != nil && c.constraint.expr == nil
   689  		var co, d string
   690  		if c.constraint != nil && c.constraint.expr != nil {
   691  			co = c.constraint.expr.String()
   692  		}
   693  		if e := c.dflt; e != nil {
   694  			d = e.String()
   695  		}
   696  		if _, err := insertColumn2.l[0].exec(&execCtx{db: ctx.db, arg: []interface{}{s.tableName, c.name, notNull, co, d}}); err != nil {
   697  			return nil, err
   698  		}
   699  	}
   700  
   701  	t.cols0 = append(t.cols0, s.c)
   702  	if err := t.constraintsAndDefaults(ctx); err != nil {
   703  		return nil, err
   704  	}
   705  
   706  	return nil, t.updated()
   707  }
   708  
   709  func (s *alterTableAddStmt) isUpdating() bool { return true }
   710  
   711  type selectStmt struct {
   712  	distinct      bool
   713  	flds          []*fld
   714  	from          *joinRset
   715  	group         *groupByRset
   716  	hasAggregates bool
   717  	limit         *limitRset
   718  	offset        *offsetRset
   719  	order         *orderByRset
   720  	where         *whereRset
   721  }
   722  
   723  func (s *selectStmt) explain(ctx *execCtx, w strutil.Formatter) {
   724  	p, err := s.plan(ctx)
   725  	if err != nil {
   726  		w.Format("ERROR: %v\n", err)
   727  		return
   728  	}
   729  
   730  	p.explain(w)
   731  }
   732  
   733  func (s *selectStmt) String() string {
   734  	var b bytes.Buffer
   735  	b.WriteString("SELECT")
   736  	if s.distinct {
   737  		b.WriteString(" DISTINCT")
   738  	}
   739  	switch {
   740  	case len(s.flds) == 0:
   741  		b.WriteString(" *")
   742  	default:
   743  		a := make([]string, len(s.flds))
   744  		for i, v := range s.flds {
   745  			s := v.expr.String()
   746  			if v.name != "" && v.name != s {
   747  				s += " AS " + v.name
   748  			}
   749  			a[i] = s
   750  		}
   751  		b.WriteString(" " + strings.Join(a, ", "))
   752  	}
   753  	b.WriteString(" FROM ")
   754  	b.WriteString(s.from.String())
   755  	if s.where != nil {
   756  		b.WriteString(" WHERE ")
   757  		b.WriteString(s.where.expr.String())
   758  	}
   759  	if s.group != nil {
   760  		b.WriteString(" GROUP BY ")
   761  		b.WriteString(strings.Join(s.group.colNames, ", "))
   762  	}
   763  	if s.order != nil {
   764  		b.WriteString(" ORDER BY ")
   765  		b.WriteString(s.order.String())
   766  	}
   767  	if s.limit != nil {
   768  		b.WriteString(" LIMIT ")
   769  		b.WriteString(s.limit.expr.String())
   770  	}
   771  	if s.offset != nil {
   772  		b.WriteString(" OFFSET ")
   773  		b.WriteString(s.offset.expr.String())
   774  	}
   775  	b.WriteRune(';')
   776  	return b.String()
   777  }
   778  
   779  func (s *selectStmt) plan(ctx *execCtx) (plan, error) { //LATER overlapping goroutines/pipelines
   780  	r, err := s.from.plan(ctx)
   781  	if err != nil {
   782  		return nil, err
   783  	}
   784  
   785  	if w := s.where; w != nil {
   786  		if r, err = (&whereRset{expr: w.expr, src: r}).plan(ctx); err != nil {
   787  			return nil, err
   788  		}
   789  	}
   790  	switch {
   791  	case !s.hasAggregates && s.group == nil: // nop
   792  	case !s.hasAggregates && s.group != nil:
   793  		if r, err = (&groupByRset{colNames: s.group.colNames, src: r}).plan(ctx); err != nil {
   794  			return nil, err
   795  		}
   796  	case s.hasAggregates && s.group == nil:
   797  		if r, err = (&groupByRset{src: r}).plan(ctx); err != nil {
   798  			return nil, err
   799  		}
   800  	case s.hasAggregates && s.group != nil:
   801  		if r, err = (&groupByRset{colNames: s.group.colNames, src: r}).plan(ctx); err != nil {
   802  			return nil, err
   803  		}
   804  	}
   805  	if r, err = (&selectRset{flds: s.flds, src: r}).plan(ctx); err != nil {
   806  		return nil, err
   807  	}
   808  
   809  	if s.distinct {
   810  		if r, err = (&distinctRset{src: r}).plan(ctx); err != nil {
   811  			return nil, err
   812  		}
   813  	}
   814  	if s := s.order; s != nil {
   815  		if r, err = (&orderByRset{asc: s.asc, by: s.by, src: r}).plan(ctx); err != nil {
   816  			return nil, err
   817  		}
   818  	}
   819  	if s := s.offset; s != nil {
   820  		if r, err = (&offsetRset{s.expr, r}).plan(ctx); err != nil {
   821  			return nil, err
   822  		}
   823  	}
   824  	if s := s.limit; s != nil {
   825  		if r, err = (&limitRset{s.expr, r}).plan(ctx); err != nil {
   826  			return nil, err
   827  		}
   828  	}
   829  	return r, nil
   830  }
   831  
   832  func (s *selectStmt) exec(ctx *execCtx) (rs Recordset, err error) {
   833  	r, err := s.plan(ctx)
   834  	if err != nil {
   835  		return nil, err
   836  	}
   837  
   838  	return recordset{ctx, r, nil}, nil
   839  }
   840  
   841  func (s *selectStmt) isUpdating() bool { return false }
   842  
   843  type insertIntoStmt struct {
   844  	colNames  []string
   845  	lists     [][]expression
   846  	sel       *selectStmt
   847  	tableName string
   848  }
   849  
   850  func (s *insertIntoStmt) explain(ctx *execCtx, w strutil.Formatter) {
   851  	w.Format("%s\n", s)
   852  }
   853  
   854  func (s *insertIntoStmt) String() string {
   855  	cn := ""
   856  	if len(s.colNames) != 0 {
   857  		cn = fmt.Sprintf(" (%s)", strings.Join(s.colNames, ", "))
   858  	}
   859  	switch {
   860  	case s.sel != nil:
   861  		return fmt.Sprintf("INSERT INTO %s%s %s;", s.tableName, cn, s.sel)
   862  	default:
   863  		a := make([]string, len(s.lists))
   864  		for i, v := range s.lists {
   865  			b := make([]string, len(v))
   866  			for i, v := range v {
   867  				b[i] = v.String()
   868  			}
   869  			a[i] = fmt.Sprintf("(%s)", strings.Join(b, ", "))
   870  		}
   871  		return fmt.Sprintf("INSERT INTO %s%s VALUES %s;", s.tableName, cn, strings.Join(a, ", "))
   872  	}
   873  }
   874  
   875  func (s *insertIntoStmt) execSelect(t *table, cols []*col, ctx *execCtx) (_ Recordset, err error) {
   876  	//TODO missing rs column number eq check
   877  	r, err := s.sel.plan(ctx)
   878  	if err != nil {
   879  		return nil, err
   880  	}
   881  
   882  	h := t.head
   883  	data0 := make([]interface{}, len(t.cols0)+2)
   884  	cc := ctx.db.cc
   885  	m := map[interface{}]interface{}{}
   886  	if err = r.do(ctx, func(_ interface{}, data []interface{}) (more bool, err error) {
   887  		for i, d := range data {
   888  			data0[cols[i].index+2] = d
   889  		}
   890  		if err = typeCheck(data0[2:], cols); err != nil {
   891  			return
   892  		}
   893  
   894  		if err = t.checkConstraintsAndDefaults(ctx, data0[2:], m); err != nil {
   895  			return false, err
   896  		}
   897  
   898  		id, err := t.store.ID()
   899  		if err != nil {
   900  			return false, err
   901  		}
   902  
   903  		data0[0] = h
   904  		data0[1] = id
   905  
   906  		// Any overflow chunks are written here.
   907  		if h, err = t.store.Create(data0...); err != nil {
   908  			return false, err
   909  		}
   910  
   911  		for i, v := range t.indices {
   912  			if v == nil {
   913  				continue
   914  			}
   915  
   916  			// Any overflow chunks are shared with the BTree key
   917  			if err = v.x.Create([]interface{}{data0[i+1]}, h); err != nil {
   918  				return false, err
   919  			}
   920  		}
   921  		for _, ix := range t.indices2 {
   922  			vlist, err := ix.eval(ctx, t.cols, id, data0[2:])
   923  			if err != nil {
   924  				return false, err
   925  			}
   926  
   927  			if err := ix.x.Create(vlist, h); err != nil {
   928  				return false, err
   929  			}
   930  		}
   931  
   932  		cc.RowsAffected++
   933  		ctx.db.root.lastInsertID = id
   934  		return true, nil
   935  	}); err != nil {
   936  		return nil, err
   937  	}
   938  
   939  	t.head = h
   940  	return nil, t.store.Update(t.hhead, h)
   941  }
   942  
   943  func (s *insertIntoStmt) exec(ctx *execCtx) (_ Recordset, err error) {
   944  	root := ctx.db.root
   945  	t, ok := root.tables[s.tableName]
   946  	if !ok {
   947  		return nil, fmt.Errorf("INSERT INTO %s: table does not exist", s.tableName)
   948  	}
   949  
   950  	var cols []*col
   951  	switch len(s.colNames) {
   952  	case 0:
   953  		cols = t.cols
   954  	default:
   955  		for _, colName := range s.colNames {
   956  			if col := findCol(t.cols, colName); col != nil {
   957  				cols = append(cols, col)
   958  				continue
   959  			}
   960  
   961  			return nil, fmt.Errorf("INSERT INTO %s: unknown column %s", s.tableName, colName)
   962  		}
   963  	}
   964  
   965  	if s.sel != nil {
   966  		return s.execSelect(t, cols, ctx)
   967  	}
   968  
   969  	for _, list := range s.lists {
   970  		if g, e := len(list), len(cols); g != e {
   971  			return nil, fmt.Errorf("INSERT INTO %s: expected %d value(s), have %d", s.tableName, e, g)
   972  		}
   973  	}
   974  
   975  	cc := ctx.db.cc
   976  	r := make([]interface{}, len(t.cols0))
   977  	m := map[interface{}]interface{}{}
   978  	for _, list := range s.lists {
   979  		for i, expr := range list {
   980  			val, err := expr.eval(ctx, m)
   981  			if err != nil {
   982  				return nil, err
   983  			}
   984  
   985  			r[cols[i].index] = val
   986  		}
   987  		if err = typeCheck(r, cols); err != nil {
   988  			return nil, err
   989  		}
   990  
   991  		if err = t.checkConstraintsAndDefaults(ctx, r, m); err != nil {
   992  			return nil, err
   993  		}
   994  
   995  		id, err := t.addRecord(ctx, r)
   996  		if err != nil {
   997  			return nil, err
   998  		}
   999  
  1000  		cc.RowsAffected++
  1001  		root.lastInsertID = id
  1002  	}
  1003  	return nil, nil
  1004  }
  1005  
  1006  func (s *insertIntoStmt) isUpdating() bool { return true }
  1007  
  1008  type beginTransactionStmt struct{}
  1009  
  1010  func (s beginTransactionStmt) explain(ctx *execCtx, w strutil.Formatter) {
  1011  	w.Format("%s\n", s)
  1012  }
  1013  
  1014  func (beginTransactionStmt) String() string { return "BEGIN TRANSACTION;" }
  1015  func (beginTransactionStmt) exec(*execCtx) (Recordset, error) {
  1016  	panic("internal error 059")
  1017  }
  1018  func (beginTransactionStmt) isUpdating() bool {
  1019  	panic("internal error 060")
  1020  }
  1021  
  1022  type commitStmt struct{}
  1023  
  1024  func (s commitStmt) explain(ctx *execCtx, w strutil.Formatter) {
  1025  	w.Format("%s\n", s)
  1026  }
  1027  
  1028  func (commitStmt) String() string { return "COMMIT;" }
  1029  func (commitStmt) exec(*execCtx) (Recordset, error) {
  1030  	panic("internal error 061")
  1031  }
  1032  func (commitStmt) isUpdating() bool {
  1033  	panic("internal error 062")
  1034  }
  1035  
  1036  type rollbackStmt struct{}
  1037  
  1038  func (s rollbackStmt) explain(ctx *execCtx, w strutil.Formatter) {
  1039  	w.Format("%s\n", s)
  1040  }
  1041  
  1042  func (rollbackStmt) String() string { return "ROLLBACK;" }
  1043  func (rollbackStmt) exec(*execCtx) (Recordset, error) {
  1044  	panic("internal error 063")
  1045  }
  1046  func (rollbackStmt) isUpdating() bool {
  1047  	panic("internal error 064")
  1048  }
  1049  
  1050  type createIndexStmt struct {
  1051  	colName     string // alt. "id()" for simple index on id()
  1052  	ifNotExists bool
  1053  	indexName   string
  1054  	tableName   string
  1055  	unique      bool
  1056  	exprList    []expression
  1057  }
  1058  
  1059  func (s *createIndexStmt) explain(ctx *execCtx, w strutil.Formatter) {
  1060  	w.Format("%s\n", s)
  1061  }
  1062  
  1063  func (s *createIndexStmt) isSimpleIndex() bool { return s.colName != "" }
  1064  
  1065  func (s *createIndexStmt) String() string {
  1066  	u := ""
  1067  	if s.unique {
  1068  		u = "UNIQUE "
  1069  	}
  1070  	e := ""
  1071  	if s.ifNotExists {
  1072  		e = "IF NOT EXISTS "
  1073  	}
  1074  	expr := s.colName
  1075  	if !s.isSimpleIndex() {
  1076  		var a []string
  1077  		for _, v := range s.exprList {
  1078  			a = append(a, v.String())
  1079  		}
  1080  		expr = strings.Join(a, ", ")
  1081  	}
  1082  	return fmt.Sprintf("CREATE %sINDEX %s%s ON %s (%s);", u, e, s.indexName, s.tableName, expr)
  1083  }
  1084  
  1085  func (s *createIndexStmt) exec(ctx *execCtx) (Recordset, error) {
  1086  	root := ctx.db.root
  1087  	if t, i := root.findIndexByName(s.indexName); i != nil {
  1088  		if s.ifNotExists {
  1089  			return nil, nil
  1090  		}
  1091  
  1092  		return nil, fmt.Errorf("CREATE INDEX: table %s already has an index named %s", t.name, s.indexName)
  1093  	}
  1094  
  1095  	if root.tables[s.indexName] != nil {
  1096  		return nil, fmt.Errorf("CREATE INDEX: index name collision with existing table: %s", s.indexName)
  1097  	}
  1098  
  1099  	t, ok := root.tables[s.tableName]
  1100  	if !ok {
  1101  		return nil, fmt.Errorf("CREATE INDEX: table does not exist %s", s.tableName)
  1102  	}
  1103  
  1104  	if findCol(t.cols, s.indexName) != nil {
  1105  		return nil, fmt.Errorf("CREATE INDEX: index name collision with existing column: %s", s.indexName)
  1106  	}
  1107  
  1108  	var h int64
  1109  	var err error
  1110  	switch {
  1111  	case s.isSimpleIndex():
  1112  		colIndex := -1
  1113  		if s.colName != "id()" {
  1114  			c := findCol(t.cols, s.colName)
  1115  			if c == nil {
  1116  				return nil, fmt.Errorf("CREATE INDEX: column does not exist: %s", s.colName)
  1117  			}
  1118  
  1119  			colIndex = c.index
  1120  		}
  1121  
  1122  		if h, err = t.addIndex(s.unique, s.indexName, colIndex); err != nil {
  1123  			return nil, fmt.Errorf("CREATE INDEX: %v", err)
  1124  		}
  1125  
  1126  		if err = t.updated(); err != nil {
  1127  			return nil, err
  1128  		}
  1129  	default:
  1130  		for _, e := range s.exprList {
  1131  			m := mentionedColumns(e)
  1132  			for colName := range m {
  1133  				c := findCol(t.cols, colName)
  1134  				if c == nil {
  1135  					return nil, fmt.Errorf("CREATE INDEX: column does not exist: %s", colName)
  1136  				}
  1137  			}
  1138  		}
  1139  		if h, err = t.addIndex2(ctx, s.unique, s.indexName, s.exprList); err != nil {
  1140  			return nil, fmt.Errorf("CREATE INDEX: %v", err)
  1141  		}
  1142  	}
  1143  
  1144  	switch ctx.db.hasIndex2 {
  1145  	case 0:
  1146  		if err := ctx.db.createIndex2(); err != nil {
  1147  			return nil, err
  1148  		}
  1149  
  1150  		if s.isSimpleIndex() {
  1151  			return nil, nil
  1152  		}
  1153  	case 1:
  1154  		return nil, nil
  1155  	case 2:
  1156  		if s.isSimpleIndex() {
  1157  			return nil, ctx.db.insertIndex2(s.tableName, s.indexName, []string{s.colName}, s.unique, true, h)
  1158  		}
  1159  	default:
  1160  		panic("internal error 011")
  1161  	}
  1162  
  1163  	exprList := make([]string, 0, len(s.exprList))
  1164  	for _, e := range s.exprList {
  1165  		exprList = append(exprList, e.String())
  1166  	}
  1167  	return nil, ctx.db.insertIndex2(s.tableName, s.indexName, exprList, s.unique, false, h)
  1168  }
  1169  
  1170  func (s *createIndexStmt) isUpdating() bool { return true }
  1171  
  1172  type createTableStmt struct {
  1173  	ifNotExists bool
  1174  	tableName   string
  1175  	cols        []*col
  1176  }
  1177  
  1178  func (s *createTableStmt) explain(ctx *execCtx, w strutil.Formatter) {
  1179  	w.Format("%s\n", s)
  1180  }
  1181  
  1182  func (s *createTableStmt) String() string {
  1183  	a := make([]string, len(s.cols))
  1184  	for i, v := range s.cols {
  1185  		var c, d string
  1186  		if x := v.constraint; x != nil {
  1187  			switch e := x.expr; {
  1188  			case e != nil:
  1189  				c = " " + e.String()
  1190  			default:
  1191  				c = " NOT NULL"
  1192  			}
  1193  		}
  1194  		if x := v.dflt; x != nil {
  1195  			d = " DEFAULT " + x.String()
  1196  		}
  1197  		a[i] = fmt.Sprintf("%s %s%s%s", v.name, typeStr(v.typ), c, d)
  1198  	}
  1199  	e := ""
  1200  	if s.ifNotExists {
  1201  		e = "IF NOT EXISTS "
  1202  	}
  1203  	return fmt.Sprintf("CREATE TABLE %s%s (%s);", e, s.tableName, strings.Join(a, ", "))
  1204  }
  1205  
  1206  func (s *createTableStmt) exec(ctx *execCtx) (_ Recordset, err error) {
  1207  	var cols []*col
  1208  	for _, v := range s.cols {
  1209  		cols = append(cols, v.clone())
  1210  	}
  1211  	root := ctx.db.root
  1212  	if _, ok := root.tables[s.tableName]; ok {
  1213  		if s.ifNotExists {
  1214  			return nil, nil
  1215  		}
  1216  
  1217  		return nil, fmt.Errorf("CREATE TABLE: table exists %s", s.tableName)
  1218  	}
  1219  
  1220  	if t, x := root.findIndexByName(s.tableName); x != nil {
  1221  		return nil, fmt.Errorf("CREATE TABLE: table %s has index %s", t.name, s.tableName)
  1222  	}
  1223  
  1224  	m := map[string]bool{}
  1225  	mustCreateColumn2 := true
  1226  	for i, c := range cols {
  1227  		nm := c.name
  1228  		if m[nm] {
  1229  			return nil, fmt.Errorf("CREATE TABLE: duplicate column %s", nm)
  1230  		}
  1231  
  1232  		m[nm] = true
  1233  		c.index = i
  1234  		if c.constraint != nil || c.dflt != nil {
  1235  			if mustCreateColumn2 {
  1236  				for _, stmt := range createColumn2.l {
  1237  					_, err := stmt.exec(&execCtx{db: ctx.db})
  1238  					if err != nil {
  1239  						return nil, err
  1240  					}
  1241  				}
  1242  			}
  1243  
  1244  			mustCreateColumn2 = false
  1245  			notNull := c.constraint != nil && c.constraint.expr == nil
  1246  			var co, d string
  1247  			if c.constraint != nil && c.constraint.expr != nil {
  1248  				co = c.constraint.expr.String()
  1249  			}
  1250  			if e := c.dflt; e != nil {
  1251  				d = e.String()
  1252  			}
  1253  			if _, err := insertColumn2.l[0].exec(&execCtx{db: ctx.db, arg: []interface{}{s.tableName, c.name, notNull, co, d}}); err != nil {
  1254  				return nil, err
  1255  			}
  1256  		}
  1257  	}
  1258  	t, err := root.createTable(s.tableName, cols)
  1259  	if err != nil {
  1260  		return nil, err
  1261  	}
  1262  
  1263  	return nil, t.constraintsAndDefaults(ctx)
  1264  }
  1265  
  1266  func (s *createTableStmt) isUpdating() bool { return true }