github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/compile/ddl.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package compile
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/compress"
    23  	"github.com/matrixorigin/matrixone/pkg/container/types"
    24  	"github.com/matrixorigin/matrixone/pkg/defines"
    25  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    26  	"github.com/matrixorigin/matrixone/pkg/sql/colexec"
    27  	"github.com/matrixorigin/matrixone/pkg/sql/util"
    28  	"github.com/matrixorigin/matrixone/pkg/util/trace"
    29  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    30  )
    31  
    32  func (s *Scope) CreateDatabase(c *Compile) error {
    33  	var span trace.Span
    34  	c.ctx, span = trace.Start(c.ctx, "CreateDatabase")
    35  	defer span.End()
    36  	dbName := s.Plan.GetDdl().GetCreateDatabase().GetDatabase()
    37  	if _, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator); err == nil {
    38  		if s.Plan.GetDdl().GetCreateDatabase().GetIfNotExists() {
    39  			return nil
    40  		}
    41  		return moerr.NewDBAlreadyExists(c.ctx, dbName)
    42  	}
    43  	err := c.e.Create(context.WithValue(c.ctx, defines.SqlKey{}, c.sql),
    44  		dbName, c.proc.TxnOperator)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	return colexec.CreateAutoIncrTable(c.e, c.ctx, c.proc, dbName)
    49  }
    50  
    51  func (s *Scope) DropDatabase(c *Compile) error {
    52  	dbName := s.Plan.GetDdl().GetDropDatabase().GetDatabase()
    53  	if _, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator); err != nil {
    54  		if s.Plan.GetDdl().GetDropDatabase().GetIfExists() {
    55  			return nil
    56  		}
    57  		return moerr.NewErrDropNonExistsDB(c.ctx, dbName)
    58  	}
    59  	return c.e.Delete(c.ctx, dbName, c.proc.TxnOperator)
    60  }
    61  
    62  // Drop the old view, and create the new view.
    63  func (s *Scope) AlterView(c *Compile) error {
    64  	qry := s.Plan.GetDdl().GetAlterView()
    65  
    66  	dbName := c.db
    67  	dbSource, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator)
    68  	if err != nil {
    69  		if qry.GetIfExists() {
    70  			return nil
    71  		}
    72  		return err
    73  	}
    74  	tblName := qry.GetTableDef().GetName()
    75  	if _, err = dbSource.Relation(c.ctx, tblName); err != nil {
    76  		if qry.GetIfExists() {
    77  			return nil
    78  		}
    79  		return err
    80  	}
    81  
    82  	// Drop view table.
    83  	if err := dbSource.Delete(c.ctx, tblName); err != nil {
    84  		return err
    85  	}
    86  
    87  	// Create view table.
    88  	// convert the plan's cols to the execution's cols
    89  	planCols := qry.GetTableDef().GetCols()
    90  	exeCols := planColsToExeCols(planCols)
    91  
    92  	// convert the plan's defs to the execution's defs
    93  	exeDefs, err := planDefsToExeDefs(qry.GetTableDef())
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	// if _, err := dbSource.Relation(c.ctx, tblName); err == nil {
    99  	//  	 return moerr.NewTableAlreadyExists(c.ctx, tblName)
   100  	// }
   101  
   102  	return dbSource.Create(context.WithValue(c.ctx, defines.SqlKey{}, c.sql), tblName, append(exeCols, exeDefs...))
   103  }
   104  
   105  func (s *Scope) CreateTable(c *Compile) error {
   106  	qry := s.Plan.GetDdl().GetCreateTable()
   107  	// convert the plan's cols to the execution's cols
   108  	planCols := qry.GetTableDef().GetCols()
   109  	tableCols := planCols
   110  	exeCols := planColsToExeCols(planCols)
   111  
   112  	// convert the plan's defs to the execution's defs
   113  	exeDefs, err := planDefsToExeDefs(qry.GetTableDef())
   114  	if err != nil {
   115  		return err
   116  	}
   117  
   118  	dbName := c.db
   119  	if qry.GetDatabase() != "" {
   120  		dbName = qry.GetDatabase()
   121  	}
   122  	dbSource, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator)
   123  	if err != nil {
   124  		if dbName == "" {
   125  			return moerr.NewNoDB(c.ctx)
   126  		}
   127  		return err
   128  	}
   129  	tblName := qry.GetTableDef().GetName()
   130  	if _, err := dbSource.Relation(c.ctx, tblName); err == nil {
   131  		if qry.GetIfNotExists() {
   132  			return nil
   133  		}
   134  		return moerr.NewTableAlreadyExists(c.ctx, tblName)
   135  	}
   136  
   137  	// check in EntireEngine.TempEngine, notice that TempEngine may not init
   138  	tmpDBSource, err := c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator)
   139  	if err == nil {
   140  		if _, err := tmpDBSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName)); err == nil {
   141  			if qry.GetIfNotExists() {
   142  				return nil
   143  			}
   144  			return moerr.NewTableAlreadyExists(c.ctx, fmt.Sprintf("temporary '%s'", tblName))
   145  		}
   146  	}
   147  
   148  	if err := dbSource.Create(context.WithValue(c.ctx, defines.SqlKey{}, c.sql), tblName, append(exeCols, exeDefs...)); err != nil {
   149  		return err
   150  	}
   151  
   152  	fkDbs := qry.GetFkDbs()
   153  	if len(fkDbs) > 0 {
   154  		fkTables := qry.GetFkTables()
   155  		newRelation, err := dbSource.Relation(c.ctx, tblName)
   156  		if err != nil {
   157  			return err
   158  		}
   159  		tblId := newRelation.GetTableID(c.ctx)
   160  
   161  		newTableDef, err := newRelation.TableDefs(c.ctx)
   162  		if err != nil {
   163  			return err
   164  		}
   165  		var colNameToId = make(map[string]uint64)
   166  		var oldCt *engine.ConstraintDef
   167  		for _, def := range newTableDef {
   168  			if attr, ok := def.(*engine.AttributeDef); ok {
   169  				colNameToId[attr.Attr.Name] = attr.Attr.ID
   170  			}
   171  			if ct, ok := def.(*engine.ConstraintDef); ok {
   172  				oldCt = ct
   173  			}
   174  		}
   175  		newFkeys := make([]*plan.ForeignKeyDef, len(qry.GetTableDef().Fkeys))
   176  		for i, fkey := range qry.GetTableDef().Fkeys {
   177  			newDef := &plan.ForeignKeyDef{
   178  				Name:        fkey.Name,
   179  				Cols:        make([]uint64, len(fkey.Cols)),
   180  				ForeignTbl:  fkey.ForeignTbl,
   181  				ForeignCols: make([]uint64, len(fkey.ForeignCols)),
   182  				OnDelete:    fkey.OnDelete,
   183  				OnUpdate:    fkey.OnUpdate,
   184  			}
   185  			copy(newDef.ForeignCols, fkey.ForeignCols)
   186  			for idx, colName := range qry.GetFkCols()[i].Cols {
   187  				newDef.Cols[idx] = colNameToId[colName]
   188  			}
   189  			newFkeys[i] = newDef
   190  		}
   191  		// remove old fk settings
   192  		newCt, err := makeNewCreateConstraint(oldCt, &engine.ForeignKeyDef{
   193  			Fkeys: newFkeys,
   194  		})
   195  		if err != nil {
   196  			return err
   197  		}
   198  		err = newRelation.UpdateConstraint(c.ctx, newCt)
   199  		if err != nil {
   200  			return err
   201  		}
   202  
   203  		// need to append TableId to parent's TableDef.RefChildTbls
   204  		for i, fkTableName := range fkTables {
   205  			fkDbName := fkDbs[i]
   206  			fkDbSource, err := c.e.Database(c.ctx, fkDbName, c.proc.TxnOperator)
   207  			if err != nil {
   208  				return err
   209  			}
   210  			fkRelation, err := fkDbSource.Relation(c.ctx, fkTableName)
   211  			if err != nil {
   212  				return err
   213  			}
   214  			fkTableDef, err := fkRelation.TableDefs(c.ctx)
   215  			if err != nil {
   216  				return err
   217  			}
   218  			var oldCt *engine.ConstraintDef
   219  			var oldRefChildDef *engine.RefChildTableDef
   220  			for _, def := range fkTableDef {
   221  				if ct, ok := def.(*engine.ConstraintDef); ok {
   222  					oldCt = ct
   223  					for _, ct := range oldCt.Cts {
   224  						if old, ok := ct.(*engine.RefChildTableDef); ok {
   225  							oldRefChildDef = old
   226  						}
   227  					}
   228  					break
   229  				}
   230  			}
   231  			if oldRefChildDef == nil {
   232  				oldRefChildDef = &engine.RefChildTableDef{}
   233  			}
   234  			oldRefChildDef.Tables = append(oldRefChildDef.Tables, tblId)
   235  			newCt, err := makeNewCreateConstraint(oldCt, oldRefChildDef)
   236  			if err != nil {
   237  				return err
   238  			}
   239  			err = fkRelation.UpdateConstraint(c.ctx, newCt)
   240  			if err != nil {
   241  				return err
   242  			}
   243  		}
   244  	}
   245  
   246  	// build index table
   247  	for _, def := range qry.IndexTables {
   248  		planCols = def.GetCols()
   249  		exeCols = planColsToExeCols(planCols)
   250  		exeDefs, err = planDefsToExeDefs(def)
   251  		if err != nil {
   252  			return err
   253  		}
   254  		if _, err := dbSource.Relation(c.ctx, def.Name); err == nil {
   255  			return moerr.NewTableAlreadyExists(c.ctx, def.Name)
   256  		}
   257  		if err := dbSource.Create(c.ctx, def.Name, append(exeCols, exeDefs...)); err != nil {
   258  			return err
   259  		}
   260  	}
   261  	return colexec.CreateAutoIncrCol(c.e, c.ctx, dbSource, c.proc, tableCols, dbName, tblName)
   262  }
   263  
   264  func (s *Scope) CreateTempTable(c *Compile) error {
   265  	qry := s.Plan.GetDdl().GetCreateTable()
   266  	// convert the plan's cols to the execution's cols
   267  	planCols := qry.GetTableDef().GetCols()
   268  	tableCols := planCols
   269  	exeCols := planColsToExeCols(planCols)
   270  
   271  	// convert the plan's defs to the execution's defs
   272  	exeDefs, err := planDefsToExeDefs(qry.GetTableDef())
   273  	if err != nil {
   274  		return err
   275  	}
   276  
   277  	// Temporary table names and persistent table names are not allowed to be duplicated
   278  	// So before create temporary table, need to check if it exists a table has same name
   279  	dbName := c.db
   280  	if qry.GetDatabase() != "" {
   281  		dbName = qry.GetDatabase()
   282  	}
   283  
   284  	// check in EntireEngine.TempEngine
   285  	tmpDBSource, err := c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator)
   286  	if err != nil {
   287  		return err
   288  	}
   289  	tblName := qry.GetTableDef().GetName()
   290  	if _, err := tmpDBSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName)); err == nil {
   291  		if qry.GetIfNotExists() {
   292  			return nil
   293  		}
   294  		return moerr.NewTableAlreadyExists(c.ctx, fmt.Sprintf("temporary '%s'", tblName))
   295  	}
   296  
   297  	// check in EntireEngine.Engine
   298  	dbSource, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator)
   299  	if err != nil {
   300  		return err
   301  	}
   302  	if _, err := dbSource.Relation(c.ctx, tblName); err == nil {
   303  		if qry.GetIfNotExists() {
   304  			return nil
   305  		}
   306  		return moerr.NewTableAlreadyExists(c.ctx, tblName)
   307  	}
   308  
   309  	// create temporary table
   310  	if err := tmpDBSource.Create(c.ctx, engine.GetTempTableName(dbName, tblName), append(exeCols, exeDefs...)); err != nil {
   311  		return err
   312  	}
   313  
   314  	// build index table
   315  	for _, def := range qry.IndexTables {
   316  		planCols = def.GetCols()
   317  		exeCols = planColsToExeCols(planCols)
   318  		exeDefs, err = planDefsToExeDefs(def)
   319  		if err != nil {
   320  			return err
   321  		}
   322  		if _, err := tmpDBSource.Relation(c.ctx, def.Name); err == nil {
   323  			return moerr.NewTableAlreadyExists(c.ctx, def.Name)
   324  		}
   325  
   326  		if err := tmpDBSource.Create(c.ctx, engine.GetTempTableName(dbName, def.Name), append(exeCols, exeDefs...)); err != nil {
   327  			return err
   328  		}
   329  	}
   330  
   331  	return colexec.CreateAutoIncrCol(c.e, c.ctx, tmpDBSource, c.proc, tableCols, defines.TEMPORARY_DBNAME, engine.GetTempTableName(dbName, tblName))
   332  }
   333  
   334  func (s *Scope) CreateIndex(c *Compile) error {
   335  	qry := s.Plan.GetDdl().GetCreateIndex()
   336  	d, err := c.e.Database(c.ctx, qry.Database, c.proc.TxnOperator)
   337  	if err != nil {
   338  		return err
   339  	}
   340  	r, err := d.Relation(c.ctx, qry.Table)
   341  	if err != nil {
   342  		return err
   343  	}
   344  
   345  	// build and create index table
   346  	if qry.TableExist {
   347  		def := qry.GetIndex().GetIndexTables()[0]
   348  		planCols := def.GetCols()
   349  		exeCols := planColsToExeCols(planCols)
   350  		exeDefs, err := planDefsToExeDefs(def)
   351  		if err != nil {
   352  			return err
   353  		}
   354  		if _, err := d.Relation(c.ctx, def.Name); err == nil {
   355  			return moerr.NewTableAlreadyExists(c.ctx, def.Name)
   356  		}
   357  		if err := d.Create(c.ctx, def.Name, append(exeCols, exeDefs...)); err != nil {
   358  			return err
   359  		}
   360  
   361  	}
   362  	// build and update constraint def
   363  	defs, err := planDefsToExeDefs(qry.GetIndex().GetTableDef())
   364  	if err != nil {
   365  		return err
   366  	}
   367  	ct := defs[0].(*engine.ConstraintDef)
   368  
   369  	tblDefs, err := r.TableDefs(c.ctx)
   370  	if err != nil {
   371  		return err
   372  	}
   373  	var oldCt *engine.ConstraintDef
   374  	for _, def := range tblDefs {
   375  		if ct, ok := def.(*engine.ConstraintDef); ok {
   376  			oldCt = ct
   377  			break
   378  		}
   379  	}
   380  	newCt, err := makeNewCreateConstraint(oldCt, ct.Cts[0])
   381  	if err != nil {
   382  		return err
   383  	}
   384  	err = r.UpdateConstraint(c.ctx, newCt)
   385  	if err != nil {
   386  		return err
   387  	}
   388  
   389  	// TODO: implement by insert ... select ...
   390  	// insert data into index table
   391  	indexDef := qry.GetIndex().GetTableDef().Indexes[0]
   392  	if indexDef.Unique {
   393  		targetAttrs := getIndexColsFromOriginTable(tblDefs, indexDef.Parts)
   394  		ret, err := r.Ranges(c.ctx, nil)
   395  		if err != nil {
   396  			return err
   397  		}
   398  		rds, err := r.NewReader(c.ctx, 1, nil, ret)
   399  		if err != nil {
   400  			return err
   401  		}
   402  		bat, err := rds[0].Read(c.ctx, targetAttrs, nil, c.proc.Mp())
   403  		if err != nil {
   404  			return err
   405  		}
   406  		err = rds[0].Close()
   407  		if err != nil {
   408  			return err
   409  		}
   410  
   411  		if bat != nil {
   412  			indexBat, cnt := util.BuildUniqueKeyBatch(bat.Vecs, targetAttrs, indexDef.Parts, qry.OriginTablePrimaryKey, c.proc)
   413  			indexR, err := d.Relation(c.ctx, indexDef.IndexTableName)
   414  			if err != nil {
   415  				return err
   416  			}
   417  			if cnt != 0 {
   418  				if err := indexR.Write(c.ctx, indexBat); err != nil {
   419  					return err
   420  				}
   421  			}
   422  			indexBat.Clean(c.proc.Mp())
   423  		}
   424  		// other situation is not supported now and check in plan
   425  	}
   426  
   427  	return nil
   428  }
   429  
   430  func (s *Scope) DropIndex(c *Compile) error {
   431  	qry := s.Plan.GetDdl().GetDropIndex()
   432  	d, err := c.e.Database(c.ctx, qry.Database, c.proc.TxnOperator)
   433  	if err != nil {
   434  		return err
   435  	}
   436  	r, err := d.Relation(c.ctx, qry.Table)
   437  	if err != nil {
   438  		return err
   439  	}
   440  
   441  	// build and update constraint def
   442  	tblDefs, err := r.TableDefs(c.ctx)
   443  	if err != nil {
   444  		return err
   445  	}
   446  	var oldCt *engine.ConstraintDef
   447  	for _, def := range tblDefs {
   448  		if ct, ok := def.(*engine.ConstraintDef); ok {
   449  			oldCt = ct
   450  			break
   451  		}
   452  	}
   453  	newCt, err := makeNewDropConstraint(oldCt, qry.GetIndexName())
   454  	if err != nil {
   455  		return err
   456  	}
   457  	err = r.UpdateConstraint(c.ctx, newCt)
   458  	if err != nil {
   459  		return err
   460  	}
   461  
   462  	// drop index table
   463  	if qry.IndexTableName != "" {
   464  		if _, err = d.Relation(c.ctx, qry.IndexTableName); err != nil {
   465  			return err
   466  		}
   467  		if err = d.Delete(c.ctx, qry.IndexTableName); err != nil {
   468  			return err
   469  		}
   470  	}
   471  	return nil
   472  }
   473  
   474  func makeNewDropConstraint(oldCt *engine.ConstraintDef, dropName string) (*engine.ConstraintDef, error) {
   475  	// must fount dropName because of being checked in plan
   476  	for i, ct := range oldCt.Cts {
   477  		switch def := ct.(type) {
   478  		case *engine.ForeignKeyDef:
   479  			for idx, fkDef := range def.Fkeys {
   480  				if fkDef.Name == dropName {
   481  					def.Fkeys = append(def.Fkeys[:idx], def.Fkeys[idx+1:]...)
   482  					oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   483  					oldCt.Cts = append(oldCt.Cts, def)
   484  					break
   485  				}
   486  			}
   487  		case *engine.IndexDef:
   488  			for idx, index := range def.Indexes {
   489  				if index.IndexName == dropName {
   490  					def.Indexes = append(def.Indexes[:idx], def.Indexes[idx+1:]...)
   491  					oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   492  					oldCt.Cts = append(oldCt.Cts, def)
   493  					break
   494  				}
   495  			}
   496  		}
   497  	}
   498  	return oldCt, nil
   499  }
   500  
   501  func makeNewCreateConstraint(oldCt *engine.ConstraintDef, c engine.Constraint) (*engine.ConstraintDef, error) {
   502  	// duplication has checked in plan
   503  	if oldCt == nil {
   504  		return &engine.ConstraintDef{
   505  			Cts: []engine.Constraint{c},
   506  		}, nil
   507  	}
   508  	switch t := c.(type) {
   509  	case *engine.ForeignKeyDef:
   510  		ok := false
   511  		for i, ct := range oldCt.Cts {
   512  			if _, ok = ct.(*engine.ForeignKeyDef); ok {
   513  				oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   514  				oldCt.Cts = append(oldCt.Cts, t)
   515  				break
   516  			}
   517  		}
   518  		if !ok {
   519  			oldCt.Cts = append(oldCt.Cts, c)
   520  		}
   521  
   522  	case *engine.RefChildTableDef:
   523  		ok := false
   524  		for i, ct := range oldCt.Cts {
   525  			if _, ok = ct.(*engine.RefChildTableDef); ok {
   526  				oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   527  				oldCt.Cts = append(oldCt.Cts, t)
   528  				break
   529  			}
   530  		}
   531  		if !ok {
   532  			oldCt.Cts = append(oldCt.Cts, c)
   533  		}
   534  	case *engine.IndexDef:
   535  		ok := false
   536  		var indexdef *engine.IndexDef
   537  		for i, ct := range oldCt.Cts {
   538  			if indexdef, ok = ct.(*engine.IndexDef); ok {
   539  				indexdef.Indexes = append(indexdef.Indexes, t.Indexes[0])
   540  				oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   541  				oldCt.Cts = append(oldCt.Cts, indexdef)
   542  				break
   543  			}
   544  		}
   545  		if !ok {
   546  			oldCt.Cts = append(oldCt.Cts, c)
   547  		}
   548  
   549  		//case *engine.UniqueIndexDef:
   550  		//	d := &plan.UniqueIndexDef{}
   551  		//	err := d.UnMarshalUniqueIndexDef([]byte(t.UniqueIndex))
   552  		//	if err != nil {
   553  		//		return nil, err
   554  		//	}
   555  		//
   556  		//	ok := false
   557  		//	var idx *engine.UniqueIndexDef
   558  		//	for i, ct := range oldCt.Cts {
   559  		//		if idx, ok = ct.(*engine.UniqueIndexDef); ok {
   560  		//			u := &plan.UniqueIndexDef{}
   561  		//			err := u.UnMarshalUniqueIndexDef([]byte(idx.UniqueIndex))
   562  		//			if err != nil {
   563  		//				return nil, err
   564  		//			}
   565  		//			u.IndexNames = append(u.IndexNames, d.IndexNames[0])
   566  		//			u.TableNames = append(u.TableNames, d.TableNames[0])
   567  		//			u.TableExists = append(u.TableExists, d.TableExists[0])
   568  		//			u.Fields = append(u.Fields, d.Fields[0])
   569  		//			u.Comments = append(u.Comments, d.Comments[0])
   570  		//
   571  		//			oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   572  		//
   573  		//			bytes, err := u.MarshalUniqueIndexDef()
   574  		//			if err != nil {
   575  		//				return nil, err
   576  		//			}
   577  		//			oldCt.Cts = append(oldCt.Cts, &engine.UniqueIndexDef{
   578  		//				UniqueIndex: string(bytes),
   579  		//			})
   580  		//			break
   581  		//		}
   582  		//	}
   583  		//	if !ok {
   584  		//		oldCt.Cts = append(oldCt.Cts, c)
   585  		//	}
   586  		//case *engine.SecondaryIndexDef:
   587  		//	d := &plan.SecondaryIndexDef{}
   588  		//	err := d.UnMarshalSecondaryIndexDef([]byte(t.SecondaryIndex))
   589  		//	if err != nil {
   590  		//		return nil, err
   591  		//	}
   592  		//
   593  		//	ok := false
   594  		//	var idx *engine.SecondaryIndexDef
   595  		//	for i, ct := range oldCt.Cts {
   596  		//		if idx, ok = ct.(*engine.SecondaryIndexDef); ok {
   597  		//			u := &plan.SecondaryIndexDef{}
   598  		//			err := u.UnMarshalSecondaryIndexDef([]byte(idx.SecondaryIndex))
   599  		//			if err != nil {
   600  		//				return nil, err
   601  		//			}
   602  		//			u.IndexNames = append(u.IndexNames, d.IndexNames[0])
   603  		//			u.TableNames = append(u.TableNames, d.TableNames[0])
   604  		//			u.TableExists = append(u.TableExists, d.TableExists[0])
   605  		//			u.Fields = append(u.Fields, d.Fields[0])
   606  		//			u.Comments = append(u.Comments, d.Comments[0])
   607  		//
   608  		//			oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...)
   609  		//
   610  		//			bytes, err := u.MarshalSecondaryIndexDef()
   611  		//			if err != nil {
   612  		//				return nil, err
   613  		//			}
   614  		//			oldCt.Cts = append(oldCt.Cts, &engine.SecondaryIndexDef{
   615  		//				SecondaryIndex: string(bytes),
   616  		//			})
   617  		//			break
   618  		//		}
   619  		//	}
   620  		//	if !ok {
   621  		//		oldCt.Cts = append(oldCt.Cts, c)
   622  		//	}
   623  	}
   624  	return oldCt, nil
   625  }
   626  
   627  // Truncation operations cannot be performed if the session holds an active table lock.
   628  func (s *Scope) TruncateTable(c *Compile) error {
   629  	var dbSource engine.Database
   630  	var rel engine.Relation
   631  	var err error
   632  	var isTemp bool
   633  	var newId uint64
   634  
   635  	tqry := s.Plan.GetDdl().GetTruncateTable()
   636  	dbName := tqry.GetDatabase()
   637  	tblName := tqry.GetTable()
   638  	oldId := tqry.GetTableId()
   639  
   640  	dbSource, err = c.e.Database(c.ctx, dbName, c.proc.TxnOperator)
   641  	if err != nil {
   642  		return err
   643  	}
   644  
   645  	if rel, err = dbSource.Relation(c.ctx, tblName); err != nil {
   646  		var e error // avoid contamination of error messages
   647  		dbSource, e = c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator)
   648  		if e != nil {
   649  			return err
   650  		}
   651  		rel, e = dbSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName))
   652  		if e != nil {
   653  			return err
   654  		}
   655  		isTemp = true
   656  	}
   657  
   658  	if isTemp {
   659  		// memoryengine truncate always return 0, so for temporary table, just use origin tableId as newId
   660  		_, err = dbSource.Truncate(c.ctx, engine.GetTempTableName(dbName, tblName))
   661  		newId = rel.GetTableID(c.ctx)
   662  	} else {
   663  		newId, err = dbSource.Truncate(c.ctx, tblName)
   664  	}
   665  
   666  	if err != nil {
   667  		return err
   668  	}
   669  
   670  	// Truncate Index Tables if needed
   671  	for _, name := range tqry.IndexTableNames {
   672  		var err error
   673  		if isTemp {
   674  			_, err = dbSource.Truncate(c.ctx, engine.GetTempTableName(dbName, name))
   675  		} else {
   676  			_, err = dbSource.Truncate(c.ctx, name)
   677  		}
   678  		if err != nil {
   679  			return err
   680  		}
   681  	}
   682  
   683  	// update tableDef of foreign key's table with new table id
   684  	for _, ftblId := range tqry.ForeignTbl {
   685  		_, _, fkRelation, err := c.e.GetRelationById(c.ctx, c.proc.TxnOperator, ftblId)
   686  		if err != nil {
   687  			return err
   688  		}
   689  		fkTableDef, err := fkRelation.TableDefs(c.ctx)
   690  		if err != nil {
   691  			return err
   692  		}
   693  		var oldCt *engine.ConstraintDef
   694  		for _, def := range fkTableDef {
   695  			if ct, ok := def.(*engine.ConstraintDef); ok {
   696  				oldCt = ct
   697  				break
   698  			}
   699  		}
   700  		for _, ct := range oldCt.Cts {
   701  			if def, ok := ct.(*engine.RefChildTableDef); ok {
   702  				for idx, refTable := range def.Tables {
   703  					if refTable == oldId {
   704  						def.Tables[idx] = newId
   705  						break
   706  					}
   707  				}
   708  				break
   709  			}
   710  		}
   711  		if err != nil {
   712  			return err
   713  		}
   714  		err = fkRelation.UpdateConstraint(c.ctx, oldCt)
   715  		if err != nil {
   716  			return err
   717  		}
   718  
   719  	}
   720  
   721  	id := rel.GetTableID(c.ctx)
   722  
   723  	if isTemp {
   724  		err = colexec.ResetAutoInsrCol(c.e, c.ctx, engine.GetTempTableName(dbName, tblName), dbSource, c.proc, id, newId, defines.TEMPORARY_DBNAME)
   725  	} else {
   726  		err = colexec.ResetAutoInsrCol(c.e, c.ctx, tblName, dbSource, c.proc, id, newId, dbName)
   727  	}
   728  	if err != nil {
   729  		return err
   730  	}
   731  
   732  	return nil
   733  }
   734  
   735  func (s *Scope) DropTable(c *Compile) error {
   736  	qry := s.Plan.GetDdl().GetDropTable()
   737  
   738  	dbName := qry.GetDatabase()
   739  	var dbSource engine.Database
   740  	var rel engine.Relation
   741  	var err error
   742  	var isTemp bool
   743  
   744  	tblName := qry.GetTable()
   745  	tblId := qry.GetTableId()
   746  
   747  	dbSource, err = c.e.Database(c.ctx, dbName, c.proc.TxnOperator)
   748  	if err != nil {
   749  		if qry.GetIfExists() {
   750  			return nil
   751  		}
   752  		return err
   753  	}
   754  
   755  	if rel, err = dbSource.Relation(c.ctx, tblName); err != nil {
   756  		var e error // avoid contamination of error messages
   757  		dbSource, e = c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator)
   758  		if dbSource == nil && qry.GetIfExists() {
   759  			return nil
   760  		} else if e != nil {
   761  			return err
   762  		}
   763  		rel, e = dbSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName))
   764  		if e != nil {
   765  			if qry.GetIfExists() {
   766  				return nil
   767  			} else {
   768  				return err
   769  			}
   770  		}
   771  		isTemp = true
   772  	}
   773  
   774  	// update tableDef of foreign key's table
   775  	for _, ftblId := range qry.ForeignTbl {
   776  		_, _, fkRelation, err := c.e.GetRelationById(c.ctx, c.proc.TxnOperator, ftblId)
   777  		if err != nil {
   778  			return err
   779  		}
   780  		fkTableDef, err := fkRelation.TableDefs(c.ctx)
   781  		if err != nil {
   782  			return err
   783  		}
   784  		var oldCt *engine.ConstraintDef
   785  		for _, def := range fkTableDef {
   786  			if ct, ok := def.(*engine.ConstraintDef); ok {
   787  				oldCt = ct
   788  				break
   789  			}
   790  		}
   791  		for _, ct := range oldCt.Cts {
   792  			if def, ok := ct.(*engine.RefChildTableDef); ok {
   793  				for idx, refTable := range def.Tables {
   794  					if refTable == tblId {
   795  						def.Tables = append(def.Tables[:idx], def.Tables[idx+1:]...)
   796  						break
   797  					}
   798  				}
   799  				break
   800  			}
   801  		}
   802  		if err != nil {
   803  			return err
   804  		}
   805  		err = fkRelation.UpdateConstraint(c.ctx, oldCt)
   806  		if err != nil {
   807  			return err
   808  		}
   809  	}
   810  
   811  	if isTemp {
   812  		if err := dbSource.Delete(c.ctx, engine.GetTempTableName(dbName, tblName)); err != nil {
   813  			return err
   814  		}
   815  		for _, name := range qry.IndexTableNames {
   816  			if err := dbSource.Delete(c.ctx, name); err != nil {
   817  				return err
   818  			}
   819  		}
   820  		return colexec.DeleteAutoIncrCol(c.e, c.ctx, dbSource, rel, c.proc, defines.TEMPORARY_DBNAME, rel.GetTableID(c.ctx))
   821  	} else {
   822  		if err := dbSource.Delete(c.ctx, tblName); err != nil {
   823  			return err
   824  		}
   825  		for _, name := range qry.IndexTableNames {
   826  			if err := dbSource.Delete(c.ctx, name); err != nil {
   827  				return err
   828  			}
   829  		}
   830  		return colexec.DeleteAutoIncrCol(c.e, c.ctx, dbSource, rel, c.proc, dbName, rel.GetTableID(c.ctx))
   831  	}
   832  }
   833  
   834  func planDefsToExeDefs(tableDef *plan.TableDef) ([]engine.TableDef, error) {
   835  	planDefs := tableDef.GetDefs()
   836  	var exeDefs []engine.TableDef
   837  	c := new(engine.ConstraintDef)
   838  	for _, def := range planDefs {
   839  		switch defVal := def.GetDef().(type) {
   840  		case *plan.TableDef_DefType_Properties:
   841  			properties := make([]engine.Property, len(defVal.Properties.GetProperties()))
   842  			for i, p := range defVal.Properties.GetProperties() {
   843  				properties[i] = engine.Property{
   844  					Key:   p.GetKey(),
   845  					Value: p.GetValue(),
   846  				}
   847  			}
   848  			exeDefs = append(exeDefs, &engine.PropertiesDef{
   849  				Properties: properties,
   850  			})
   851  			//case *plan.TableDef_DefType_UIdx:
   852  			//	bytes, err := defVal.UIdx.MarshalUniqueIndexDef()
   853  			//	if err != nil {
   854  			//		return nil, err
   855  			//	}
   856  			//	c.Cts = append(c.Cts, &engine.UniqueIndexDef{
   857  			//		UniqueIndex: string(bytes),
   858  			//	})
   859  			//case *plan.TableDef_DefType_SIdx:
   860  			//	bytes, err := defVal.SIdx.MarshalSecondaryIndexDef()
   861  			//	if err != nil {
   862  			//		return nil, err
   863  			//	}
   864  			//	c.Cts = append(c.Cts, &engine.SecondaryIndexDef{
   865  			//		SecondaryIndex: string(bytes),
   866  			//	})
   867  		}
   868  	}
   869  
   870  	if tableDef.Indexes != nil {
   871  		c.Cts = append(c.Cts, &engine.IndexDef{
   872  			Indexes: tableDef.Indexes,
   873  		})
   874  
   875  		//bytes, err := tableDef.Index.Marshal()
   876  		//if err != nil {
   877  		//	return nil, err
   878  		//}
   879  		//
   880  		//c.Cts = append(c.Cts, &engine.IndexesDef{
   881  		//	Indexes: string(bytes),
   882  		//})
   883  	}
   884  
   885  	if tableDef.Partition != nil {
   886  		bytes, err := tableDef.Partition.MarshalPartitionInfo()
   887  		if err != nil {
   888  			return nil, err
   889  		}
   890  		exeDefs = append(exeDefs, &engine.PartitionDef{
   891  			Partition: string(bytes),
   892  		})
   893  	}
   894  
   895  	if tableDef.ViewSql != nil {
   896  		exeDefs = append(exeDefs, &engine.ViewDef{
   897  			View: tableDef.ViewSql.View,
   898  		})
   899  	}
   900  
   901  	if len(tableDef.Fkeys) > 0 {
   902  		c.Cts = append(c.Cts, &engine.ForeignKeyDef{
   903  			Fkeys: tableDef.Fkeys,
   904  		})
   905  	}
   906  
   907  	if tableDef.Pkey != nil {
   908  		c.Cts = append(c.Cts, &engine.PrimaryKeyDef{
   909  			Pkey: tableDef.Pkey,
   910  		})
   911  	}
   912  
   913  	if len(tableDef.RefChildTbls) > 0 {
   914  		c.Cts = append(c.Cts, &engine.RefChildTableDef{
   915  			Tables: tableDef.RefChildTbls,
   916  		})
   917  	}
   918  
   919  	if len(c.Cts) > 0 {
   920  		exeDefs = append(exeDefs, c)
   921  	}
   922  
   923  	if tableDef.ClusterBy != nil {
   924  		exeDefs = append(exeDefs, &engine.ClusterByDef{
   925  			Name: tableDef.ClusterBy.Name,
   926  		})
   927  	}
   928  	return exeDefs, nil
   929  }
   930  
   931  func planColsToExeCols(planCols []*plan.ColDef) []engine.TableDef {
   932  	exeCols := make([]engine.TableDef, len(planCols))
   933  	for i, col := range planCols {
   934  		var alg compress.T
   935  		switch col.Alg {
   936  		case plan.CompressType_None:
   937  			alg = compress.None
   938  		case plan.CompressType_Lz4:
   939  			alg = compress.Lz4
   940  		}
   941  		colTyp := col.GetTyp()
   942  		exeCols[i] = &engine.AttributeDef{
   943  			Attr: engine.Attribute{
   944  				Name: col.Name,
   945  				Alg:  alg,
   946  				Type: types.Type{
   947  					Oid:       types.T(colTyp.GetId()),
   948  					Width:     colTyp.GetWidth(),
   949  					Precision: colTyp.GetPrecision(),
   950  					Scale:     colTyp.GetScale(),
   951  					Size:      colTyp.GetSize(),
   952  				},
   953  				Default:       planCols[i].GetDefault(),
   954  				OnUpdate:      planCols[i].GetOnUpdate(),
   955  				Primary:       col.GetPrimary(),
   956  				Comment:       col.GetComment(),
   957  				ClusterBy:     col.ClusterBy,
   958  				AutoIncrement: col.Typ.GetAutoIncr(),
   959  			},
   960  		}
   961  	}
   962  	return exeCols
   963  }
   964  
   965  // Get the required columns of the index table from the original table
   966  func getIndexColsFromOriginTable(tblDefs []engine.TableDef, indexColumns []string) []string {
   967  	colNameMap := make(map[string]int)
   968  	for _, tbldef := range tblDefs {
   969  		if constraintDef, ok := tbldef.(*engine.ConstraintDef); ok {
   970  			for _, ct := range constraintDef.Cts {
   971  				if pk, ok2 := ct.(*engine.PrimaryKeyDef); ok2 {
   972  					for _, name := range pk.Pkey.Names {
   973  						colNameMap[name] = 1
   974  					}
   975  					break
   976  				}
   977  			}
   978  		}
   979  	}
   980  
   981  	for _, column := range indexColumns {
   982  		colNameMap[column] = 1
   983  	}
   984  
   985  	j := 0
   986  	keys := make([]string, len(colNameMap))
   987  	for k := range colNameMap {
   988  		keys[j] = k
   989  		j++
   990  	}
   991  	return keys
   992  }