github.com/mithrandie/csvq@v1.18.1/lib/query/query.go (about)

     1  package query
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"sync/atomic"
     7  
     8  	"github.com/mithrandie/csvq/lib/option"
     9  	"github.com/mithrandie/csvq/lib/parser"
    10  	"github.com/mithrandie/csvq/lib/value"
    11  )
    12  
    13  func FetchCursor(ctx context.Context, scope *ReferenceScope, name parser.Identifier, fetchPosition parser.FetchPosition, vars []parser.Variable) (bool, error) {
    14  	position := parser.NEXT
    15  	number := -1
    16  	if !fetchPosition.Position.IsEmpty() {
    17  		position = fetchPosition.Position.Token
    18  		if fetchPosition.Number != nil {
    19  			p, err := Evaluate(ctx, scope, fetchPosition.Number)
    20  			if err != nil {
    21  				return false, err
    22  			}
    23  			i := value.ToInteger(p)
    24  			if value.IsNull(i) {
    25  				return false, NewInvalidFetchPositionError(fetchPosition)
    26  			}
    27  			number = int(i.(*value.Integer).Raw())
    28  			value.Discard(i)
    29  		}
    30  	}
    31  
    32  	primaries, err := scope.FetchCursor(name, position, number)
    33  	if err != nil {
    34  		return false, err
    35  	}
    36  	if primaries == nil {
    37  		return false, nil
    38  	}
    39  	if len(vars) != len(primaries) {
    40  		return false, NewCursorFetchLengthError(name, len(primaries))
    41  	}
    42  
    43  	for i, v := range vars {
    44  		_, err := scope.SubstituteVariableDirectly(v, primaries[i])
    45  		if err != nil {
    46  			return false, err
    47  		}
    48  	}
    49  	return true, nil
    50  }
    51  
    52  func DeclareView(ctx context.Context, scope *ReferenceScope, expr parser.ViewDeclaration) error {
    53  	if scope.TemporaryTableExists(expr.View.Literal) {
    54  		return NewTemporaryTableRedeclaredError(expr.View)
    55  	}
    56  
    57  	var view *View
    58  	var err error
    59  
    60  	if expr.Query != nil {
    61  		view, err = Select(ctx, scope, expr.Query.(parser.SelectQuery))
    62  		if err != nil {
    63  			return err
    64  		}
    65  
    66  		if err := view.Header.Update(expr.View.Literal, expr.Fields); err != nil {
    67  			if _, ok := err.(*FieldLengthNotMatchError); ok {
    68  				return NewTemporaryTableFieldLengthError(expr.Query.(parser.SelectQuery), expr.View, len(expr.Fields))
    69  			}
    70  			return err
    71  		}
    72  	} else {
    73  		fields := make([]string, len(expr.Fields))
    74  		fieldsMap := make(map[string]bool, len(expr.Fields))
    75  		for i := range expr.Fields {
    76  			lit := expr.Fields[i].(parser.Identifier).Literal
    77  			ulit := strings.ToUpper(lit)
    78  			if _, ok := fieldsMap[ulit]; ok {
    79  				return NewDuplicateFieldNameError(expr.Fields[i].(parser.Identifier))
    80  			}
    81  			fields[i] = lit
    82  			fieldsMap[ulit] = true
    83  		}
    84  		header := NewHeader(expr.View.Literal, fields)
    85  		view = NewView()
    86  		view.Header = header
    87  		view.RecordSet = RecordSet{}
    88  	}
    89  
    90  	view.FileInfo = NewTemporaryTableFileInfo(expr.View.Literal)
    91  	view.CreateRestorePoint()
    92  
    93  	scope.SetTemporaryTable(view)
    94  
    95  	return err
    96  }
    97  
    98  func Select(ctx context.Context, scope *ReferenceScope, query parser.SelectQuery) (*View, error) {
    99  	var intoVars []parser.Variable = nil
   100  	if selectEntity, ok := query.SelectEntity.(parser.SelectEntity); ok && selectEntity.IntoClause != nil {
   101  		intoClause := selectEntity.IntoClause.(parser.IntoClause)
   102  		if len(selectEntity.SelectClause.(parser.SelectClause).Fields) != len(intoClause.Variables) {
   103  			return nil, NewSelectIntoQueryFieldLengthNotMatchError(query, len(intoClause.Variables))
   104  		}
   105  		for _, v := range intoClause.Variables {
   106  			if _, err := scope.GetVariable(v); err != nil {
   107  				return nil, err
   108  			}
   109  		}
   110  		intoVars = intoClause.Variables
   111  	}
   112  
   113  	queryScope := scope.CreateNode()
   114  
   115  	if query.WithClause != nil {
   116  		if err := queryScope.LoadInlineTable(ctx, query.WithClause.(parser.WithClause)); err != nil {
   117  			queryScope.CloseCurrentNode()
   118  			return nil, err
   119  		}
   120  	}
   121  
   122  	view, err := selectEntity(
   123  		ctx,
   124  		queryScope,
   125  		query.SelectEntity,
   126  		query.IsForUpdate(),
   127  	)
   128  	if err != nil {
   129  		queryScope.CloseCurrentNode()
   130  		return nil, err
   131  	}
   132  
   133  	if query.OrderByClause != nil {
   134  		if err := view.OrderBy(ctx, queryScope, query.OrderByClause.(parser.OrderByClause)); err != nil {
   135  			queryScope.CloseCurrentNode()
   136  			return nil, err
   137  		}
   138  	}
   139  
   140  	if query.LimitClause != nil {
   141  		limitClause := query.LimitClause.(parser.LimitClause)
   142  		if limitClause.OffsetClause != nil {
   143  			if err := view.Offset(ctx, queryScope, limitClause.OffsetClause.(parser.OffsetClause)); err != nil {
   144  				queryScope.CloseCurrentNode()
   145  				return nil, err
   146  			}
   147  		}
   148  
   149  		if !limitClause.Type.IsEmpty() {
   150  			if err := view.Limit(ctx, queryScope, limitClause); err != nil {
   151  				queryScope.CloseCurrentNode()
   152  				return nil, err
   153  			}
   154  		}
   155  	}
   156  
   157  	err = view.Fix(ctx, queryScope.Tx.Flags)
   158  	queryScope.CloseCurrentNode()
   159  
   160  	if err == nil && intoVars != nil {
   161  		if view.FieldLen() != len(intoVars) {
   162  			return nil, NewSelectIntoQueryFieldLengthNotMatchError(query, len(intoVars))
   163  		}
   164  		switch view.RecordLen() {
   165  		case 0:
   166  			for _, v := range intoVars {
   167  				if _, err := scope.SubstituteVariableDirectly(v, value.NewNull()); err != nil {
   168  					return view, err
   169  				}
   170  			}
   171  		case 1:
   172  			for i, v := range intoVars {
   173  				if _, err := scope.SubstituteVariableDirectly(v, view.RecordSet[0][i][0]); err != nil {
   174  					return view, err
   175  				}
   176  			}
   177  		default:
   178  			return view, NewSelectIntoQueryTooManyRecordsError(query)
   179  		}
   180  	}
   181  
   182  	return view, err
   183  }
   184  
   185  func selectEntity(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression, forUpdate bool) (*View, error) {
   186  	entity, ok := expr.(parser.SelectEntity)
   187  	if !ok {
   188  		return selectSet(ctx, scope, expr.(parser.SelectSet), forUpdate)
   189  	}
   190  
   191  	if entity.FromClause == nil {
   192  		entity.FromClause = parser.FromClause{}
   193  	}
   194  	view, err := LoadView(ctx, scope, entity.FromClause.(parser.FromClause).Tables, forUpdate, false)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	if entity.WhereClause != nil {
   200  		if err := view.Where(ctx, scope, entity.WhereClause.(parser.WhereClause)); err != nil {
   201  			return nil, err
   202  		}
   203  	}
   204  
   205  	if entity.GroupByClause != nil {
   206  		if err := view.GroupBy(ctx, scope, entity.GroupByClause.(parser.GroupByClause)); err != nil {
   207  			return nil, err
   208  		}
   209  	}
   210  
   211  	if entity.HavingClause != nil {
   212  		if err := view.Having(ctx, scope, entity.HavingClause.(parser.HavingClause)); err != nil {
   213  			return nil, err
   214  		}
   215  	}
   216  
   217  	if err := view.Select(ctx, scope, entity.SelectClause.(parser.SelectClause)); err != nil {
   218  		return nil, err
   219  	}
   220  
   221  	return view, nil
   222  }
   223  
   224  func selectSetEntity(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression, forUpdate bool) (*View, error) {
   225  	if subquery, ok := expr.(parser.Subquery); ok {
   226  		return Select(ctx, scope, subquery.Query)
   227  	}
   228  
   229  	view, err := selectEntity(ctx, scope, expr, forUpdate)
   230  	if err != nil {
   231  		return nil, err
   232  	}
   233  	err = view.Fix(ctx, scope.Tx.Flags)
   234  	return view, err
   235  }
   236  
   237  func selectSet(ctx context.Context, scope *ReferenceScope, set parser.SelectSet, forUpdate bool) (*View, error) {
   238  	lview, err := selectSetEntity(ctx, scope, set.LHS, forUpdate)
   239  	if err != nil {
   240  		return nil, err
   241  	}
   242  
   243  	if scope.RecursiveTable != nil {
   244  		scope.RecursiveTmpView = nil
   245  		err := selectSetForRecursion(ctx, scope, lview, set, forUpdate)
   246  		if err != nil {
   247  			return nil, err
   248  		}
   249  	} else {
   250  		queryScope := scope.CreateNode()
   251  		rview, err := selectSetEntity(ctx, queryScope, set.RHS, forUpdate)
   252  		queryScope.CloseCurrentNode()
   253  		queryScope = nil
   254  		if err != nil {
   255  			return nil, err
   256  		}
   257  
   258  		if lview.FieldLen() != rview.FieldLen() {
   259  			return nil, NewCombinedSetFieldLengthError(set.RHS, lview.FieldLen())
   260  		}
   261  
   262  		switch set.Operator.Token {
   263  		case parser.UNION:
   264  			if err = lview.Union(ctx, scope.Tx.Flags, rview, !set.All.IsEmpty()); err != nil {
   265  				return nil, err
   266  			}
   267  		case parser.EXCEPT:
   268  			if err = lview.Except(ctx, scope.Tx.Flags, rview, !set.All.IsEmpty()); err != nil {
   269  				return nil, err
   270  			}
   271  		case parser.INTERSECT:
   272  			if err = lview.Intersect(ctx, scope.Tx.Flags, rview, !set.All.IsEmpty()); err != nil {
   273  				return nil, err
   274  			}
   275  		}
   276  	}
   277  
   278  	err = lview.SelectAllColumns(ctx, scope)
   279  	return lview, err
   280  }
   281  
   282  func selectSetForRecursion(ctx context.Context, scope *ReferenceScope, view *View, set parser.SelectSet, forUpdate bool) error {
   283  	if ctx.Err() != nil {
   284  		return ConvertContextError(ctx.Err())
   285  	}
   286  
   287  	if -1 < scope.Tx.Flags.LimitRecursion {
   288  		if scope.RecursiveCount == nil {
   289  			scope.RecursiveCount = new(int64)
   290  		}
   291  		atomic.AddInt64(scope.RecursiveCount, 1)
   292  		if scope.Tx.Flags.LimitRecursion < *scope.RecursiveCount {
   293  			return NewRecursionExceededLimitError(set.RHS, scope.Tx.Flags.LimitRecursion)
   294  		}
   295  	}
   296  
   297  	tmpViewName := strings.ToUpper(scope.RecursiveTable.Name.Literal)
   298  
   299  	if scope.RecursiveTmpView == nil {
   300  		err := view.Header.Update(tmpViewName, scope.RecursiveTable.Fields)
   301  		if err != nil {
   302  			return err
   303  		}
   304  		scope.RecursiveTmpView = view
   305  	}
   306  
   307  	queryScope := scope.CreateNode()
   308  	rview, err := selectSetEntity(ctx, queryScope, set.RHS, forUpdate)
   309  	queryScope.CloseCurrentNode()
   310  	queryScope = nil
   311  	if err != nil {
   312  		return err
   313  	}
   314  	if view.FieldLen() != rview.FieldLen() {
   315  		return NewCombinedSetFieldLengthError(set.RHS, view.FieldLen())
   316  	}
   317  
   318  	if rview.RecordLen() < 1 {
   319  		return nil
   320  	}
   321  
   322  	switch set.Operator.Token {
   323  	case parser.UNION:
   324  		if err = view.Union(ctx, scope.Tx.Flags, rview, !set.All.IsEmpty()); err != nil {
   325  			return err
   326  		}
   327  	case parser.EXCEPT:
   328  		if err = view.Except(ctx, scope.Tx.Flags, rview, !set.All.IsEmpty()); err != nil {
   329  			return err
   330  		}
   331  	case parser.INTERSECT:
   332  		if err = view.Intersect(ctx, scope.Tx.Flags, rview, !set.All.IsEmpty()); err != nil {
   333  			return err
   334  		}
   335  	}
   336  
   337  	if err = rview.Header.Update(tmpViewName, scope.RecursiveTable.Fields); err != nil {
   338  		return err
   339  	}
   340  	scope.RecursiveTmpView = rview
   341  
   342  	return selectSetForRecursion(ctx, scope, view, set, forUpdate)
   343  }
   344  
   345  func Insert(ctx context.Context, scope *ReferenceScope, query parser.InsertQuery) (*FileInfo, int, error) {
   346  	queryScope := scope.CreateNode()
   347  	defer queryScope.CloseCurrentNode()
   348  
   349  	var insertRecords int
   350  
   351  	if query.WithClause != nil {
   352  		if err := queryScope.LoadInlineTable(ctx, query.WithClause.(parser.WithClause)); err != nil {
   353  			return nil, insertRecords, err
   354  		}
   355  	}
   356  
   357  	tables := []parser.QueryExpression{
   358  		query.Table,
   359  	}
   360  
   361  	queryScope.Tx.operationMutex.Lock()
   362  	defer queryScope.Tx.operationMutex.Unlock()
   363  
   364  	view, err := LoadView(ctx, queryScope, tables, true, false)
   365  	if err != nil {
   366  		return nil, insertRecords, err
   367  	}
   368  	if !view.IsUpdatable() {
   369  		return nil, insertRecords, NewInlineTableCannotBeUpdatedError(query.Table.Object)
   370  	}
   371  
   372  	fields := query.Fields
   373  	if fields == nil {
   374  		fields = view.Header.TableColumns()
   375  	}
   376  
   377  	if query.ValuesList != nil {
   378  		if insertRecords, err = view.InsertValues(ctx, queryScope, fields, query.ValuesList); err != nil {
   379  			return nil, insertRecords, err
   380  		}
   381  	} else {
   382  		if insertRecords, err = view.InsertFromQuery(ctx, queryScope, fields, query.Query.(parser.SelectQuery)); err != nil {
   383  			return nil, insertRecords, err
   384  		}
   385  	}
   386  
   387  	if err = view.RestoreHeaderReferences(); err != nil {
   388  		return nil, insertRecords, err
   389  	}
   390  
   391  	if view.FileInfo.IsInMemoryTable() {
   392  		scope.ReplaceTemporaryTable(view)
   393  	} else if view.FileInfo.IsFile() {
   394  		scope.Tx.CachedViews.Set(view)
   395  	}
   396  
   397  	return view.FileInfo, insertRecords, err
   398  }
   399  
   400  func Update(ctx context.Context, scope *ReferenceScope, query parser.UpdateQuery) ([]*FileInfo, []int, error) {
   401  	queryScope := scope.CreateNode()
   402  	defer queryScope.CloseCurrentNode()
   403  
   404  	if query.WithClause != nil {
   405  		if err := queryScope.LoadInlineTable(ctx, query.WithClause.(parser.WithClause)); err != nil {
   406  			return nil, nil, err
   407  		}
   408  	}
   409  
   410  	if query.FromClause == nil {
   411  		query.FromClause = parser.FromClause{Tables: query.Tables}
   412  	}
   413  
   414  	queryScope.Tx.operationMutex.Lock()
   415  	defer queryScope.Tx.operationMutex.Unlock()
   416  
   417  	view, err := LoadView(ctx, queryScope, query.FromClause.(parser.FromClause).Tables, true, true)
   418  	if err != nil {
   419  		return nil, nil, err
   420  	}
   421  
   422  	if query.WhereClause != nil {
   423  		if err := view.Where(ctx, queryScope, query.WhereClause.(parser.WhereClause)); err != nil {
   424  			return nil, nil, err
   425  		}
   426  	}
   427  
   428  	viewsToUpdate := make(map[string]*View)
   429  	updatedCount := make(map[string]int)
   430  	for _, v := range query.Tables {
   431  		table := v.(parser.Table)
   432  		tableName, err := ParseTableName(ctx, queryScope, table)
   433  		if err != nil {
   434  			return nil, nil, err
   435  		}
   436  		if len(tableName.Literal) < 1 {
   437  			return nil, nil, NewAliasMustBeSpecifiedForUpdateError(table.Object)
   438  		}
   439  
   440  		fpath, err := queryScope.GetAlias(tableName)
   441  		if err != nil {
   442  			return nil, nil, err
   443  		}
   444  		if len(fpath) < 1 {
   445  			return nil, nil, NewInlineTableCannotBeUpdatedError(table.Object)
   446  		}
   447  		viewKey := strings.ToUpper(tableName.Literal)
   448  
   449  		if queryScope.TemporaryTableExists(fpath) {
   450  			viewsToUpdate[viewKey], _ = queryScope.GetTemporaryTable(parser.Identifier{Literal: fpath})
   451  		} else {
   452  			viewsToUpdate[viewKey], err = queryScope.Tx.CachedViews.Get(fpath)
   453  			if err != nil {
   454  				return nil, nil, NewInlineTableCannotBeUpdatedError(table.Object)
   455  			}
   456  		}
   457  		if err = viewsToUpdate[viewKey].Header.Update(tableName.Literal, nil); err != nil {
   458  			return nil, nil, err
   459  		}
   460  	}
   461  
   462  	updatesList := make(map[string]map[int]*UintPool)
   463  	seqScope := queryScope.CreateScopeForSequentialEvaluation(view)
   464  	for i := range view.RecordSet {
   465  		seqScope.Records[0].recordIndex = i
   466  		internalIds := make(map[string]int)
   467  		setListLen := len(query.SetList)
   468  
   469  		for _, uset := range query.SetList {
   470  			val, err := Evaluate(ctx, seqScope, uset.Value)
   471  			if err != nil {
   472  				return nil, nil, err
   473  			}
   474  
   475  			viewref, err := view.FieldViewName(uset.Field)
   476  			if err != nil {
   477  				return nil, nil, err
   478  			}
   479  			viewref = strings.ToUpper(viewref)
   480  
   481  			if _, ok := viewsToUpdate[viewref]; !ok {
   482  				return nil, nil, NewUpdateFieldNotExistError(uset.Field)
   483  			}
   484  
   485  			var internalId int
   486  			if id, ok := internalIds[viewref]; ok {
   487  				internalId = id
   488  			} else {
   489  				id, err := view.InternalRecordId(viewref, i)
   490  				if err != nil {
   491  					return nil, nil, NewUpdateValueAmbiguousError(uset.Field, uset.Value)
   492  				}
   493  
   494  				internalId = id
   495  				internalIds[viewref] = internalId
   496  			}
   497  
   498  			fieldIdx, _ := viewsToUpdate[viewref].Header.SearchIndex(uset.Field)
   499  			if _, ok := updatesList[viewref]; !ok {
   500  				updatesList[viewref] = make(map[int]*UintPool)
   501  			}
   502  			if _, ok := updatesList[viewref][internalId]; !ok {
   503  				updatesList[viewref][internalId] = NewUintPool(setListLen, LimitToUseUintSlicePool)
   504  				updatedCount[viewref]++
   505  			}
   506  			if updatesList[viewref][internalId].Exists(uint(fieldIdx)) {
   507  				return nil, nil, NewUpdateValueAmbiguousError(uset.Field, uset.Value)
   508  			}
   509  			updatesList[viewref][internalId].Add(uint(fieldIdx))
   510  			viewsToUpdate[viewref].RecordSet[internalId][fieldIdx] = NewCell(val)
   511  		}
   512  	}
   513  
   514  	fileInfos := make([]*FileInfo, 0)
   515  	updateRecords := make([]int, 0)
   516  	for k, v := range viewsToUpdate {
   517  		if err = v.RestoreHeaderReferences(); err != nil {
   518  			return nil, nil, err
   519  		}
   520  
   521  		if v.FileInfo.IsInMemoryTable() {
   522  			scope.ReplaceTemporaryTable(v)
   523  		} else if v.FileInfo.IsFile() {
   524  			scope.Tx.CachedViews.Set(v)
   525  		}
   526  
   527  		fileInfos = append(fileInfos, v.FileInfo)
   528  		updateRecords = append(updateRecords, updatedCount[k])
   529  	}
   530  
   531  	return fileInfos, updateRecords, nil
   532  }
   533  
   534  func Replace(ctx context.Context, scope *ReferenceScope, query parser.ReplaceQuery) (*FileInfo, int, error) {
   535  	queryScope := scope.CreateNode()
   536  	defer queryScope.CloseCurrentNode()
   537  
   538  	var replaceRecords int
   539  
   540  	if query.WithClause != nil {
   541  		if err := queryScope.LoadInlineTable(ctx, query.WithClause.(parser.WithClause)); err != nil {
   542  			return nil, replaceRecords, err
   543  		}
   544  	}
   545  
   546  	tables := []parser.QueryExpression{
   547  		query.Table,
   548  	}
   549  
   550  	queryScope.Tx.operationMutex.Lock()
   551  	defer queryScope.Tx.operationMutex.Unlock()
   552  
   553  	view, err := LoadView(ctx, queryScope, tables, true, false)
   554  	if err != nil {
   555  		return nil, replaceRecords, err
   556  	}
   557  	if !view.IsUpdatable() {
   558  		return nil, replaceRecords, NewInlineTableCannotBeUpdatedError(query.Table.Object)
   559  	}
   560  
   561  	fields := query.Fields
   562  	if fields == nil {
   563  		fields = view.Header.TableColumns()
   564  	}
   565  
   566  	if query.ValuesList != nil {
   567  		if replaceRecords, err = view.ReplaceValues(ctx, queryScope, fields, query.ValuesList, query.Keys); err != nil {
   568  			return nil, replaceRecords, err
   569  		}
   570  	} else {
   571  		if replaceRecords, err = view.ReplaceFromQuery(ctx, queryScope, fields, query.Query.(parser.SelectQuery), query.Keys); err != nil {
   572  			return nil, replaceRecords, err
   573  		}
   574  	}
   575  
   576  	if err = view.RestoreHeaderReferences(); err != nil {
   577  		return nil, replaceRecords, err
   578  	}
   579  
   580  	if view.FileInfo.IsInMemoryTable() {
   581  		scope.ReplaceTemporaryTable(view)
   582  	} else if view.FileInfo.IsFile() {
   583  		scope.Tx.CachedViews.Set(view)
   584  	}
   585  
   586  	return view.FileInfo, replaceRecords, err
   587  }
   588  
   589  func Delete(ctx context.Context, scope *ReferenceScope, query parser.DeleteQuery) ([]*FileInfo, []int, error) {
   590  	queryScope := scope.CreateNode()
   591  	defer queryScope.CloseCurrentNode()
   592  
   593  	if query.WithClause != nil {
   594  		if err := queryScope.LoadInlineTable(ctx, query.WithClause.(parser.WithClause)); err != nil {
   595  			return nil, nil, err
   596  		}
   597  	}
   598  
   599  	tables := query.FromClause.Tables
   600  	if query.Tables == nil {
   601  		if 1 < len(tables) {
   602  			return nil, nil, NewDeleteTableNotSpecifiedError(query)
   603  		}
   604  		query.Tables = tables
   605  	}
   606  
   607  	queryScope.Tx.operationMutex.Lock()
   608  	defer queryScope.Tx.operationMutex.Unlock()
   609  
   610  	view, err := LoadView(ctx, queryScope, tables, true, true)
   611  	if err != nil {
   612  		return nil, nil, err
   613  	}
   614  
   615  	if query.WhereClause != nil {
   616  		if err := view.Where(ctx, queryScope, query.WhereClause.(parser.WhereClause)); err != nil {
   617  			return nil, nil, err
   618  		}
   619  	}
   620  
   621  	viewsToDelete := make(map[string]*View)
   622  	deletedIndices := make(map[string]map[int]bool)
   623  	for _, v := range query.Tables {
   624  		table := v.(parser.Table)
   625  		tableName, err := ParseTableName(ctx, queryScope, table)
   626  		if err != nil {
   627  			return nil, nil, err
   628  		}
   629  		if len(tableName.Literal) < 1 {
   630  			return nil, nil, NewAliasMustBeSpecifiedForUpdateError(table.Object)
   631  		}
   632  
   633  		fpath, err := queryScope.GetAlias(tableName)
   634  		if err != nil {
   635  			return nil, nil, err
   636  		}
   637  		if len(fpath) < 1 {
   638  			return nil, nil, NewInlineTableCannotBeUpdatedError(table.Object)
   639  		}
   640  		viewKey := strings.ToUpper(tableName.Literal)
   641  
   642  		if queryScope.TemporaryTableExists(fpath) {
   643  			viewsToDelete[viewKey], _ = queryScope.GetTemporaryTable(parser.Identifier{Literal: fpath})
   644  		} else {
   645  			viewsToDelete[viewKey], err = queryScope.Tx.CachedViews.Get(fpath)
   646  			if err != nil {
   647  				return nil, nil, NewInlineTableCannotBeUpdatedError(table.Object)
   648  			}
   649  		}
   650  		if err = viewsToDelete[viewKey].Header.Update(tableName.Literal, nil); err != nil {
   651  			return nil, nil, err
   652  		}
   653  		deletedIndices[viewKey] = make(map[int]bool)
   654  	}
   655  
   656  	for i := range view.RecordSet {
   657  		if ctx.Err() != nil {
   658  			return nil, nil, ConvertContextError(ctx.Err())
   659  		}
   660  
   661  		for viewref := range viewsToDelete {
   662  			internalId, err := view.InternalRecordId(viewref, i)
   663  			if err != nil {
   664  				continue
   665  			}
   666  			if !deletedIndices[viewref][internalId] {
   667  				deletedIndices[viewref][internalId] = true
   668  			}
   669  		}
   670  	}
   671  
   672  	fileInfos := make([]*FileInfo, 0)
   673  	deletedCounts := make([]int, 0)
   674  	for k, v := range viewsToDelete {
   675  		if ctx.Err() != nil {
   676  			return nil, nil, ConvertContextError(ctx.Err())
   677  		}
   678  
   679  		records := make(RecordSet, 0, v.RecordLen()-len(deletedIndices[k]))
   680  		for i, record := range v.RecordSet {
   681  			if !deletedIndices[k][i] {
   682  				records = append(records, record)
   683  			}
   684  		}
   685  		v.RecordSet = records
   686  
   687  		if err = v.RestoreHeaderReferences(); err != nil {
   688  			return nil, nil, err
   689  		}
   690  
   691  		if v.FileInfo.IsInMemoryTable() {
   692  			scope.ReplaceTemporaryTable(v)
   693  		} else if v.FileInfo.IsFile() {
   694  			scope.Tx.CachedViews.Set(v)
   695  		}
   696  
   697  		fileInfos = append(fileInfos, v.FileInfo)
   698  		deletedCounts = append(deletedCounts, len(deletedIndices[k]))
   699  	}
   700  
   701  	return fileInfos, deletedCounts, nil
   702  }
   703  
   704  func CreateTable(ctx context.Context, scope *ReferenceScope, query parser.CreateTable) (*FileInfo, error) {
   705  	queryScope := scope.CreateNode()
   706  	defer queryScope.CloseCurrentNode()
   707  
   708  	var view *View
   709  
   710  	flags := queryScope.Tx.Flags
   711  	fileInfo, err := NewFileInfoForCreate(query.Table, flags.Repository, flags.ExportOptions.Delimiter, flags.ExportOptions.Encoding)
   712  	if err != nil {
   713  		return nil, err
   714  	}
   715  	h, err := queryScope.Tx.FileContainer.CreateHandlerForCreate(fileInfo.Path)
   716  	if err != nil {
   717  		query.Table.Literal = fileInfo.Path
   718  		return nil, ConvertFileHandlerError(err, query.Table)
   719  	}
   720  	fileInfo.Handler = h
   721  
   722  	fileInfo.LineBreak = flags.ExportOptions.LineBreak
   723  	fileInfo.EncloseAll = flags.ExportOptions.EncloseAll
   724  	fileInfo.NoHeader = flags.ExportOptions.WithoutHeader
   725  	fileInfo.PrettyPrint = flags.ExportOptions.PrettyPrint
   726  	fileInfo.ForUpdate = true
   727  
   728  	if query.Query != nil {
   729  		view, err = Select(ctx, queryScope, query.Query.(parser.SelectQuery))
   730  		if err != nil {
   731  			return nil, appendCompositeError(err, queryScope.Tx.FileContainer.Close(fileInfo.Handler))
   732  		}
   733  
   734  		if err = view.Header.Update(FormatTableName(fileInfo.Path), query.Fields); err != nil {
   735  			if _, ok := err.(*FieldLengthNotMatchError); ok {
   736  				err = NewTableFieldLengthError(query.Query.(parser.SelectQuery), query.Table, len(query.Fields))
   737  			}
   738  			return nil, appendCompositeError(err, queryScope.Tx.FileContainer.Close(fileInfo.Handler))
   739  		}
   740  	} else {
   741  		fields := make([]string, len(query.Fields))
   742  		fieldsMap := make(map[string]bool, len(query.Fields))
   743  		for i := range query.Fields {
   744  			lit := query.Fields[i].(parser.Identifier).Literal
   745  			ulit := strings.ToUpper(lit)
   746  			if _, ok := fieldsMap[ulit]; ok {
   747  				err = NewDuplicateFieldNameError(query.Fields[i].(parser.Identifier))
   748  				return nil, appendCompositeError(err, queryScope.Tx.FileContainer.Close(fileInfo.Handler))
   749  			}
   750  			fields[i] = lit
   751  			fieldsMap[ulit] = true
   752  		}
   753  		header := NewHeader(FormatTableName(fileInfo.Path), fields)
   754  		view = &View{
   755  			Header:    header,
   756  			RecordSet: RecordSet{},
   757  		}
   758  	}
   759  
   760  	view.FileInfo = fileInfo
   761  
   762  	scope.Tx.CachedViews.Set(view)
   763  
   764  	return view.FileInfo, nil
   765  }
   766  
   767  func AddColumns(ctx context.Context, scope *ReferenceScope, query parser.AddColumns) (*FileInfo, int, error) {
   768  	queryScope := scope.CreateNode()
   769  	defer queryScope.CloseCurrentNode()
   770  
   771  	if query.Position == nil {
   772  		query.Position = parser.ColumnPosition{
   773  			Position: parser.Token{Token: parser.LAST, Literal: parser.TokenLiteral(parser.LAST)},
   774  		}
   775  	}
   776  
   777  	queryScope.Tx.operationMutex.Lock()
   778  	defer queryScope.Tx.operationMutex.Unlock()
   779  
   780  	view, err := LoadViewFromTableIdentifier(ctx, queryScope, query.Table, true, false)
   781  	if err != nil {
   782  		return nil, 0, err
   783  	}
   784  	if !view.IsUpdatable() {
   785  		return nil, 0, NewInlineTableCannotBeUpdatedError(query.Table)
   786  	}
   787  
   788  	var insertPos int
   789  	pos, _ := query.Position.(parser.ColumnPosition)
   790  	switch pos.Position.Token {
   791  	case parser.FIRST:
   792  		insertPos = 0
   793  	case parser.LAST:
   794  		insertPos = view.FieldLen()
   795  	default:
   796  		idx, err := view.FieldIndex(pos.Column)
   797  		if err != nil {
   798  			return nil, 0, err
   799  		}
   800  		switch pos.Position.Token {
   801  		case parser.BEFORE:
   802  			insertPos = idx
   803  		default: //parser.AFTER
   804  			insertPos = idx + 1
   805  		}
   806  	}
   807  
   808  	newFieldLen := view.FieldLen() + len(query.Columns)
   809  	columnNames := view.Header.TableColumnNames()
   810  	columnNamesMap := make(map[string]bool, newFieldLen)
   811  	for i := range columnNames {
   812  		columnNamesMap[strings.ToUpper(columnNames[i])] = true
   813  	}
   814  
   815  	fields := make([]string, len(query.Columns))
   816  	defaults := make([]parser.QueryExpression, len(query.Columns))
   817  	for i, coldef := range query.Columns {
   818  		ulit := strings.ToUpper(coldef.Column.Literal)
   819  		if _, ok := columnNamesMap[ulit]; ok {
   820  			return nil, 0, NewDuplicateFieldNameError(coldef.Column)
   821  		}
   822  		fields[i] = coldef.Column.Literal
   823  		defaults[i] = coldef.Value
   824  		columnNamesMap[ulit] = true
   825  	}
   826  
   827  	addHeader := NewHeader(FormatTableName(view.FileInfo.Path), fields)
   828  	header := make(Header, newFieldLen)
   829  	for i, v := range view.Header {
   830  		var idx int
   831  		if i < insertPos {
   832  			idx = i
   833  		} else {
   834  			idx = i + len(fields)
   835  		}
   836  		header[idx] = v
   837  	}
   838  	for i, v := range addHeader {
   839  		header[i+insertPos] = v
   840  	}
   841  	colNumber := 0
   842  	for i := range header {
   843  		colNumber++
   844  		header[i].Number = colNumber
   845  	}
   846  
   847  	records := make(RecordSet, view.RecordLen())
   848  
   849  	if err := EvaluateSequentially(ctx, queryScope, view, func(seqScope *ReferenceScope, rIdx int) error {
   850  		record := make(Record, newFieldLen)
   851  		for i, cell := range view.RecordSet[rIdx] {
   852  			var cellIdx int
   853  			if i < insertPos {
   854  				cellIdx = i
   855  			} else {
   856  				cellIdx = i + len(fields)
   857  			}
   858  			record[cellIdx] = cell
   859  		}
   860  
   861  		for i, v := range defaults {
   862  			if v == nil {
   863  				v = parser.NewNullValue()
   864  			}
   865  			val, e := Evaluate(ctx, seqScope, v)
   866  			if e != nil {
   867  				return e
   868  			}
   869  			record[i+insertPos] = NewCell(val)
   870  		}
   871  		records[rIdx] = record
   872  		return nil
   873  	}); err != nil {
   874  		return nil, 0, err
   875  	}
   876  
   877  	view.Header = header
   878  	view.RecordSet = records
   879  
   880  	if view.FileInfo.IsInMemoryTable() {
   881  		scope.ReplaceTemporaryTable(view)
   882  	} else if view.FileInfo.IsFile() {
   883  		scope.Tx.CachedViews.Set(view)
   884  	}
   885  
   886  	return view.FileInfo, len(fields), err
   887  }
   888  
   889  func DropColumns(ctx context.Context, scope *ReferenceScope, query parser.DropColumns) (*FileInfo, int, error) {
   890  	queryScope := scope.CreateNode()
   891  	defer queryScope.CloseCurrentNode()
   892  
   893  	queryScope.Tx.operationMutex.Lock()
   894  	defer queryScope.Tx.operationMutex.Unlock()
   895  
   896  	view, err := LoadViewFromTableIdentifier(ctx, queryScope, query.Table, true, false)
   897  	if err != nil {
   898  		return nil, 0, err
   899  	}
   900  	if !view.IsUpdatable() {
   901  		return nil, 0, NewInlineTableCannotBeUpdatedError(query.Table)
   902  	}
   903  
   904  	dropIndices := NewUintPool(len(query.Columns), LimitToUseUintSlicePool)
   905  	for _, v := range query.Columns {
   906  		idx, err := view.FieldIndex(v)
   907  		if err != nil {
   908  			return nil, 0, err
   909  		}
   910  		if !dropIndices.Exists(uint(idx)) {
   911  			dropIndices.Add(uint(idx))
   912  		}
   913  	}
   914  
   915  	view.selectFields = []int{}
   916  	for i := 0; i < view.FieldLen(); i++ {
   917  		if view.Header[i].IsFromTable && !dropIndices.Exists(uint(i)) {
   918  			view.selectFields = append(view.selectFields, i)
   919  		}
   920  	}
   921  
   922  	if err = view.Fix(ctx, scope.Tx.Flags); err != nil {
   923  		return nil, 0, err
   924  	}
   925  
   926  	if view.FileInfo.IsInMemoryTable() {
   927  		scope.ReplaceTemporaryTable(view)
   928  	} else if view.FileInfo.IsFile() {
   929  		scope.Tx.CachedViews.Set(view)
   930  	}
   931  
   932  	return view.FileInfo, dropIndices.Len(), err
   933  
   934  }
   935  
   936  func RenameColumn(ctx context.Context, scope *ReferenceScope, query parser.RenameColumn) (*FileInfo, error) {
   937  	queryScope := scope.CreateNode()
   938  	defer queryScope.CloseCurrentNode()
   939  
   940  	queryScope.Tx.operationMutex.Lock()
   941  	defer queryScope.Tx.operationMutex.Unlock()
   942  
   943  	view, err := LoadViewFromTableIdentifier(ctx, queryScope, query.Table, true, false)
   944  	if err != nil {
   945  		return nil, err
   946  	}
   947  	if !view.IsUpdatable() {
   948  		return nil, NewInlineTableCannotBeUpdatedError(query.Table)
   949  	}
   950  
   951  	columnNames := view.Header.TableColumnNames()
   952  	columnNamesMap := make(map[string]bool, len(columnNames))
   953  	for i := range columnNames {
   954  		columnNamesMap[strings.ToUpper(columnNames[i])] = true
   955  	}
   956  	if _, ok := columnNamesMap[strings.ToUpper(query.New.Literal)]; ok {
   957  		return nil, NewDuplicateFieldNameError(query.New)
   958  	}
   959  
   960  	idx, err := view.FieldIndex(query.Old)
   961  	if err != nil {
   962  		return nil, err
   963  	}
   964  
   965  	view.Header[idx].Column = query.New.Literal
   966  
   967  	if view.FileInfo.IsInMemoryTable() {
   968  		scope.ReplaceTemporaryTable(view)
   969  	} else if view.FileInfo.IsFile() {
   970  		scope.Tx.CachedViews.Set(view)
   971  	}
   972  
   973  	return view.FileInfo, err
   974  }
   975  
   976  func SetTableAttribute(ctx context.Context, scope *ReferenceScope, query parser.SetTableAttribute) (*FileInfo, string, error) {
   977  	var log string
   978  
   979  	queryScope := scope.CreateNode()
   980  	defer queryScope.CloseCurrentNode()
   981  
   982  	queryScope.Tx.operationMutex.Lock()
   983  	defer queryScope.Tx.operationMutex.Unlock()
   984  
   985  	view, err := LoadViewFromTableIdentifier(ctx, queryScope, query.Table, true, false)
   986  	if err != nil {
   987  		return nil, log, err
   988  	}
   989  	if !view.FileInfo.IsFile() {
   990  		return nil, log, NewNotTableError(query.Table)
   991  	}
   992  
   993  	var p value.Primary
   994  	if ident, ok := query.Value.(parser.Identifier); ok {
   995  		p = value.NewString(ident.Literal)
   996  	} else {
   997  		p, err = Evaluate(ctx, scope, query.Value)
   998  		if err != nil {
   999  			return nil, log, err
  1000  		}
  1001  	}
  1002  
  1003  	fileInfo := view.FileInfo
  1004  	attr := strings.ToUpper(query.Attribute.Literal)
  1005  	switch attr {
  1006  	case TableDelimiter, TableDelimiterPositions, TableFormat, TableEncoding, TableLineBreak, TableJsonEscape:
  1007  		s := value.ToString(p)
  1008  		if value.IsNull(s) {
  1009  			return nil, log, NewTableAttributeValueNotAllowedFormatError(query)
  1010  		}
  1011  		switch attr {
  1012  		case TableDelimiter:
  1013  			err = fileInfo.SetDelimiter(s.(*value.String).Raw())
  1014  		case TableDelimiterPositions:
  1015  			err = fileInfo.SetDelimiterPositions(s.(*value.String).Raw())
  1016  		case TableFormat:
  1017  			err = fileInfo.SetFormat(s.(*value.String).Raw())
  1018  		case TableEncoding:
  1019  			err = fileInfo.SetEncoding(s.(*value.String).Raw())
  1020  		case TableLineBreak:
  1021  			err = fileInfo.SetLineBreak(s.(*value.String).Raw())
  1022  		case TableJsonEscape:
  1023  			err = fileInfo.SetJsonEscape(s.(*value.String).Raw())
  1024  		}
  1025  		value.Discard(s)
  1026  	case TableHeader, TableEncloseAll, TablePrettyPrint:
  1027  		b := value.ToBoolean(p)
  1028  		if value.IsNull(b) {
  1029  			return nil, log, NewTableAttributeValueNotAllowedFormatError(query)
  1030  		}
  1031  		switch attr {
  1032  		case TableHeader:
  1033  			err = fileInfo.SetNoHeader(!b.(*value.Boolean).Raw())
  1034  		case TableEncloseAll:
  1035  			err = fileInfo.SetEncloseAll(b.(*value.Boolean).Raw())
  1036  		case TablePrettyPrint:
  1037  			err = fileInfo.SetPrettyPrint(b.(*value.Boolean).Raw())
  1038  		}
  1039  	default:
  1040  		return nil, log, NewInvalidTableAttributeNameError(query.Attribute)
  1041  	}
  1042  
  1043  	if err != nil {
  1044  		if _, ok := err.(*TableAttributeUnchangedError); ok {
  1045  			return nil, log, err
  1046  		}
  1047  		return nil, log, NewInvalidTableAttributeValueError(query, err.Error())
  1048  	}
  1049  
  1050  	w := scope.Tx.CreateDocumentWriter()
  1051  	w.WriteColorWithoutLineBreak("Path: ", option.LableEffect)
  1052  	w.WriteColorWithoutLineBreak(fileInfo.Path, option.ObjectEffect)
  1053  	w.NewLine()
  1054  	writeTableAttribute(w, scope.Tx.Flags, fileInfo)
  1055  	w.NewLine()
  1056  
  1057  	w.Title1 = "Attributes Updated in"
  1058  	if i, ok := query.Table.(parser.Identifier); ok {
  1059  		w.Title2 = i.Literal
  1060  	} else if to, ok := query.Table.(parser.FormatSpecifiedFunction); ok {
  1061  		if pi, ok := to.Path.(parser.Identifier); ok {
  1062  			w.Title2 = pi.Literal
  1063  		}
  1064  	}
  1065  	w.Title2Effect = option.IdentifierEffect
  1066  	log = "\n" + w.String() + "\n"
  1067  
  1068  	scope.Tx.CachedViews.Set(view)
  1069  	return view.FileInfo, log, err
  1070  }