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

     1  package query
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/mithrandie/csvq/lib/option"
    14  	"github.com/mithrandie/csvq/lib/parser"
    15  	"github.com/mithrandie/csvq/lib/value"
    16  
    17  	"github.com/mithrandie/go-text"
    18  	"github.com/mithrandie/go-text/json"
    19  )
    20  
    21  var loadViewTests = []struct {
    22  	Name               string
    23  	TestCache          bool
    24  	Encoding           text.Encoding
    25  	NoHeader           bool
    26  	From               parser.FromClause
    27  	ForUpdate          bool
    28  	UseInternalId      bool
    29  	Stdin              string
    30  	ImportFormat       option.Format
    31  	Delimiter          rune
    32  	AllowUnevenFields  bool
    33  	DelimiterPositions []int
    34  	SingleLine         bool
    35  	JsonQuery          string
    36  	WithoutNull        bool
    37  	Scope              *ReferenceScope
    38  	Result             *View
    39  	ResultScope        *ReferenceScope
    40  	Error              string
    41  }{
    42  	{
    43  		Name: "Dual View",
    44  		From: parser.FromClause{
    45  			Tables: []parser.QueryExpression{
    46  				parser.Table{Object: parser.Dual{}},
    47  			},
    48  		},
    49  		Result: &View{
    50  			Header: []HeaderField{{}},
    51  			RecordSet: []Record{
    52  				{
    53  					NewCell(value.NewNull()),
    54  				},
    55  			},
    56  		},
    57  	},
    58  	{
    59  		Name: "Dual View With Omitted FromClause",
    60  		From: parser.FromClause{},
    61  		Result: &View{
    62  			Header: []HeaderField{{}},
    63  			RecordSet: []Record{
    64  				{
    65  					NewCell(value.NewNull()),
    66  				},
    67  			},
    68  		},
    69  	},
    70  	{
    71  		Name: "LoadView File",
    72  		From: parser.FromClause{
    73  			Tables: []parser.QueryExpression{
    74  				parser.Table{
    75  					Object: parser.Identifier{Literal: "table1.csv"},
    76  				},
    77  			},
    78  		},
    79  		Result: &View{
    80  			Header: NewHeader("table1", []string{"column1", "column2"}),
    81  			RecordSet: []Record{
    82  				NewRecord([]value.Primary{
    83  					value.NewString("1"),
    84  					value.NewString("str1"),
    85  				}),
    86  				NewRecord([]value.Primary{
    87  					value.NewString("2"),
    88  					value.NewString("str2"),
    89  				}),
    90  				NewRecord([]value.Primary{
    91  					value.NewString("3"),
    92  					value.NewString("str3"),
    93  				}),
    94  			},
    95  			FileInfo: &FileInfo{
    96  				Path:      "table1.csv",
    97  				Delimiter: ',',
    98  				Encoding:  text.UTF8,
    99  				LineBreak: text.LF,
   100  			},
   101  		},
   102  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   103  			{scopeNameAliases: {
   104  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
   105  			}},
   106  		}, time.Time{}, nil),
   107  	},
   108  	{
   109  		Name: "LoadView File ForUpdate",
   110  		From: parser.FromClause{
   111  			Tables: []parser.QueryExpression{
   112  				parser.Table{
   113  					Object: parser.Identifier{Literal: "table1.csv"},
   114  				},
   115  			},
   116  		},
   117  		ForUpdate: true,
   118  		Result: &View{
   119  			Header: NewHeader("table1", []string{"column1", "column2"}),
   120  			RecordSet: []Record{
   121  				NewRecord([]value.Primary{
   122  					value.NewString("1"),
   123  					value.NewString("str1"),
   124  				}),
   125  				NewRecord([]value.Primary{
   126  					value.NewString("2"),
   127  					value.NewString("str2"),
   128  				}),
   129  				NewRecord([]value.Primary{
   130  					value.NewString("3"),
   131  					value.NewString("str3"),
   132  				}),
   133  			},
   134  			FileInfo: &FileInfo{
   135  				Path:      "table1.csv",
   136  				Delimiter: ',',
   137  				Encoding:  text.UTF8,
   138  				LineBreak: text.LF,
   139  				ForUpdate: true,
   140  			},
   141  		},
   142  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{{
   143  			scopeNameAliases: {
   144  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
   145  			},
   146  		}}, time.Time{}, nil),
   147  	},
   148  	{
   149  		Name:      "LoadView from Cached View",
   150  		TestCache: true,
   151  		From: parser.FromClause{
   152  			Tables: []parser.QueryExpression{
   153  				parser.Table{
   154  					Object: parser.Identifier{Literal: "table1"},
   155  				},
   156  			},
   157  		},
   158  		ForUpdate: true,
   159  		Result: &View{
   160  			Header: NewHeader("table1", []string{"column1", "column2"}),
   161  			RecordSet: []Record{
   162  				NewRecord([]value.Primary{
   163  					value.NewString("1"),
   164  					value.NewString("str1"),
   165  				}),
   166  				NewRecord([]value.Primary{
   167  					value.NewString("2"),
   168  					value.NewString("str2"),
   169  				}),
   170  				NewRecord([]value.Primary{
   171  					value.NewString("3"),
   172  					value.NewString("str3"),
   173  				}),
   174  			},
   175  			FileInfo: &FileInfo{
   176  				Path:      "table1.csv",
   177  				Delimiter: ',',
   178  				Encoding:  text.UTF8,
   179  				LineBreak: text.LF,
   180  				ForUpdate: true,
   181  			},
   182  		},
   183  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{{
   184  			scopeNameAliases: {
   185  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
   186  			},
   187  		}}, time.Time{}, nil),
   188  	},
   189  	{
   190  		Name: "LoadView File with UTF-8 BOM",
   191  		From: parser.FromClause{
   192  			Tables: []parser.QueryExpression{
   193  				parser.Table{
   194  					Object: parser.Identifier{Literal: "table1_bom.csv"},
   195  				},
   196  			},
   197  		},
   198  		Result: &View{
   199  			Header: NewHeader("table1_bom", []string{"column1", "column2"}),
   200  			RecordSet: []Record{
   201  				NewRecord([]value.Primary{
   202  					value.NewString("1"),
   203  					value.NewString("str1"),
   204  				}),
   205  				NewRecord([]value.Primary{
   206  					value.NewString("2"),
   207  					value.NewString("str2"),
   208  				}),
   209  				NewRecord([]value.Primary{
   210  					value.NewString("3"),
   211  					value.NewString("str3"),
   212  				}),
   213  			},
   214  			FileInfo: &FileInfo{
   215  				Path:      "table1_bom.csv",
   216  				Delimiter: ',',
   217  				Encoding:  text.UTF8M,
   218  				LineBreak: text.LF,
   219  			},
   220  		},
   221  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   222  			{scopeNameAliases: {
   223  				"TABLE1_BOM": strings.ToUpper(GetTestFilePath("table1_bom.csv")),
   224  			}},
   225  		}, time.Time{}, nil),
   226  	},
   227  	{
   228  		Name: "LoadView with Parentheses",
   229  		From: parser.FromClause{
   230  			Tables: []parser.QueryExpression{
   231  				parser.Parentheses{
   232  					Expr: parser.Table{
   233  						Object: parser.Identifier{Literal: "table1.csv"},
   234  					},
   235  				},
   236  			},
   237  		},
   238  		Result: &View{
   239  			Header: NewHeader("table1", []string{"column1", "column2"}),
   240  			RecordSet: []Record{
   241  				NewRecord([]value.Primary{
   242  					value.NewString("1"),
   243  					value.NewString("str1"),
   244  				}),
   245  				NewRecord([]value.Primary{
   246  					value.NewString("2"),
   247  					value.NewString("str2"),
   248  				}),
   249  				NewRecord([]value.Primary{
   250  					value.NewString("3"),
   251  					value.NewString("str3"),
   252  				}),
   253  			},
   254  			FileInfo: &FileInfo{
   255  				Path:      "table1.csv",
   256  				Delimiter: ',',
   257  				Encoding:  text.UTF8,
   258  				LineBreak: text.LF,
   259  			},
   260  		},
   261  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   262  			{scopeNameAliases: {
   263  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
   264  			}},
   265  		}, time.Time{}, nil),
   266  	},
   267  	{
   268  		Name: "LoadView From Stdin",
   269  		From: parser.FromClause{
   270  			Tables: []parser.QueryExpression{
   271  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   272  			},
   273  		},
   274  		Stdin: "column1,column2\n1,\"str1\"",
   275  		Result: &View{
   276  			Header: NewHeader("t", []string{"column1", "column2"}),
   277  			RecordSet: []Record{
   278  				NewRecord([]value.Primary{
   279  					value.NewString("1"),
   280  					value.NewString("str1"),
   281  				}),
   282  			},
   283  			FileInfo: &FileInfo{
   284  				Path:      "STDIN",
   285  				Delimiter: ',',
   286  				Encoding:  text.UTF8,
   287  				LineBreak: text.LF,
   288  				ViewType:  ViewTypeStdin,
   289  			},
   290  		},
   291  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   292  			{
   293  				scopeNameTempTables: {
   294  					"STDIN": &View{
   295  						FileInfo: &FileInfo{Path: "STDIN"},
   296  					},
   297  				},
   298  			},
   299  		}, []map[string]map[string]interface{}{
   300  			{scopeNameAliases: {
   301  				"T": "STDIN",
   302  			}},
   303  		}, time.Time{}, nil),
   304  	},
   305  	{
   306  		Name: "LoadView From Stdin ForUpdate",
   307  		From: parser.FromClause{
   308  			Tables: []parser.QueryExpression{
   309  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   310  			},
   311  		},
   312  		Stdin:     "column1,column2\n1,\"str1\"",
   313  		ForUpdate: true,
   314  		Result: &View{
   315  			Header: NewHeader("t", []string{"column1", "column2"}),
   316  			RecordSet: []Record{
   317  				NewRecord([]value.Primary{
   318  					value.NewString("1"),
   319  					value.NewString("str1"),
   320  				}),
   321  			},
   322  			FileInfo: &FileInfo{
   323  				Path:      "STDIN",
   324  				Delimiter: ',',
   325  				Encoding:  text.UTF8,
   326  				LineBreak: text.LF,
   327  				ViewType:  ViewTypeStdin,
   328  			},
   329  		},
   330  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   331  			{
   332  				scopeNameTempTables: {
   333  					"STDIN": &View{
   334  						FileInfo: &FileInfo{Path: "STDIN"},
   335  					},
   336  				},
   337  			},
   338  		}, []map[string]map[string]interface{}{
   339  			{
   340  				scopeNameAliases: {
   341  					"T": "STDIN",
   342  				},
   343  			},
   344  		}, time.Time{}, nil),
   345  	},
   346  	{
   347  		Name: "LoadView TSV From Stdin",
   348  		From: parser.FromClause{
   349  			Tables: []parser.QueryExpression{
   350  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   351  			},
   352  		},
   353  		Stdin:        "column1\tcolumn2\n1\t\"str1\"",
   354  		ImportFormat: option.TSV,
   355  		Result: &View{
   356  			Header: NewHeader("t", []string{"column1", "column2"}),
   357  			RecordSet: []Record{
   358  				NewRecord([]value.Primary{
   359  					value.NewString("1"),
   360  					value.NewString("str1"),
   361  				}),
   362  			},
   363  			FileInfo: &FileInfo{
   364  				Path:      "STDIN",
   365  				Format:    option.TSV,
   366  				Delimiter: '\t',
   367  				Encoding:  text.UTF8,
   368  				LineBreak: text.LF,
   369  				ViewType:  ViewTypeStdin,
   370  			},
   371  		},
   372  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   373  			{
   374  				scopeNameTempTables: {
   375  					"STDIN": &View{
   376  						FileInfo: &FileInfo{Path: "STDIN"},
   377  					},
   378  				},
   379  			},
   380  		}, []map[string]map[string]interface{}{
   381  			{scopeNameAliases: {
   382  				"T": "STDIN",
   383  			}},
   384  		}, time.Time{}, nil),
   385  	},
   386  	{
   387  		Name: "LoadView From Stdin With Internal Id",
   388  		From: parser.FromClause{
   389  			Tables: []parser.QueryExpression{
   390  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   391  			},
   392  		},
   393  		UseInternalId: true,
   394  		Stdin:         "column1,column2\n1,\"str1\"",
   395  		Result: &View{
   396  			Header: NewHeaderWithId("t", []string{"column1", "column2"}),
   397  			RecordSet: []Record{
   398  				NewRecordWithId(0, []value.Primary{
   399  					value.NewString("1"),
   400  					value.NewString("str1"),
   401  				}),
   402  			},
   403  			FileInfo: &FileInfo{
   404  				Path:      "STDIN",
   405  				Delimiter: ',',
   406  				Encoding:  text.UTF8,
   407  				LineBreak: text.LF,
   408  				ViewType:  ViewTypeStdin,
   409  			},
   410  		},
   411  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   412  			{
   413  				scopeNameTempTables: {
   414  					"STDIN": &View{
   415  						FileInfo: &FileInfo{Path: "STDIN"},
   416  					},
   417  				},
   418  			},
   419  		}, []map[string]map[string]interface{}{
   420  			{
   421  				scopeNameAliases: {
   422  					"T": "STDIN",
   423  				},
   424  			},
   425  		}, time.Time{}, nil),
   426  	},
   427  	{
   428  		Name: "LoadView Json From Stdin",
   429  		From: parser.FromClause{
   430  			Tables: []parser.QueryExpression{
   431  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   432  			},
   433  		},
   434  		Stdin:        "{\"key\":[{\"column1\": 1, \"column2\": \"str1\"}]}",
   435  		ImportFormat: option.JSON,
   436  		JsonQuery:    "key{}",
   437  		Result: &View{
   438  			Header: NewHeader("t", []string{"column1", "column2"}),
   439  			RecordSet: []Record{
   440  				NewRecord([]value.Primary{
   441  					value.NewFloat(1),
   442  					value.NewString("str1"),
   443  				}),
   444  			},
   445  			FileInfo: &FileInfo{
   446  				Path:      "STDIN",
   447  				Delimiter: ',',
   448  				JsonQuery: "key{}",
   449  				Format:    option.JSON,
   450  				Encoding:  text.UTF8,
   451  				LineBreak: text.LF,
   452  				ViewType:  ViewTypeStdin,
   453  			},
   454  		},
   455  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   456  			{
   457  				scopeNameTempTables: {
   458  					"STDIN": &View{
   459  						FileInfo: &FileInfo{Path: "STDIN"},
   460  					},
   461  				},
   462  			},
   463  		}, []map[string]map[string]interface{}{
   464  			{scopeNameAliases: {
   465  				"T": "STDIN",
   466  			}},
   467  		}, time.Time{}, nil),
   468  	},
   469  	{
   470  		Name: "LoadView Json Lines From Stdin",
   471  		From: parser.FromClause{
   472  			Tables: []parser.QueryExpression{
   473  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   474  			},
   475  		},
   476  		Stdin:        "{\"column1\": 1, \"column2\": \"str1\"}\n{\"column1\": 2, \"column2\": \"str2\"}",
   477  		ImportFormat: option.JSONL,
   478  		JsonQuery:    "",
   479  		Result: &View{
   480  			Header: NewHeader("t", []string{"column1", "column2"}),
   481  			RecordSet: []Record{
   482  				NewRecord([]value.Primary{
   483  					value.NewFloat(1),
   484  					value.NewString("str1"),
   485  				}),
   486  				NewRecord([]value.Primary{
   487  					value.NewFloat(2),
   488  					value.NewString("str2"),
   489  				}),
   490  			},
   491  			FileInfo: &FileInfo{
   492  				Path:      "STDIN",
   493  				Delimiter: ',',
   494  				JsonQuery: "",
   495  				Format:    option.JSONL,
   496  				Encoding:  text.UTF8,
   497  				LineBreak: text.LF,
   498  				ViewType:  ViewTypeStdin,
   499  			},
   500  		},
   501  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   502  			{
   503  				scopeNameTempTables: {
   504  					"STDIN": &View{
   505  						FileInfo: &FileInfo{Path: "STDIN"},
   506  					},
   507  				},
   508  			},
   509  		}, []map[string]map[string]interface{}{
   510  			{scopeNameAliases: {
   511  				"T": "STDIN",
   512  			}},
   513  		}, time.Time{}, nil),
   514  	},
   515  	{
   516  		Name: "LoadView Json Lines From Stdin, Json Structure Error",
   517  		From: parser.FromClause{
   518  			Tables: []parser.QueryExpression{
   519  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   520  			},
   521  		},
   522  		Stdin:        "{\"column1\": 1, \"column2\": \"str1\"}\n\"str\"",
   523  		ImportFormat: option.JSONL,
   524  		JsonQuery:    "",
   525  		Error:        "json lines must be an array of objects",
   526  	},
   527  	{
   528  		Name: "LoadView JsonH From Stdin",
   529  		From: parser.FromClause{
   530  			Tables: []parser.QueryExpression{
   531  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   532  			},
   533  		},
   534  		Stdin:        "[{\"item1\": \"value\\u00221\",\"item2\": 1},{\"item1\": \"value2\",\"item2\": 2}]",
   535  		ImportFormat: option.JSON,
   536  		JsonQuery:    "{}",
   537  		Result: &View{
   538  			Header: NewHeader("t", []string{"item1", "item2"}),
   539  			RecordSet: []Record{
   540  				NewRecord([]value.Primary{
   541  					value.NewString("value\"1"),
   542  					value.NewFloat(1),
   543  				}),
   544  				NewRecord([]value.Primary{
   545  					value.NewString("value2"),
   546  					value.NewFloat(2),
   547  				}),
   548  			},
   549  			FileInfo: &FileInfo{
   550  				Path:       "STDIN",
   551  				Delimiter:  ',',
   552  				JsonQuery:  "{}",
   553  				Format:     option.JSON,
   554  				Encoding:   text.UTF8,
   555  				LineBreak:  text.LF,
   556  				JsonEscape: json.HexDigits,
   557  				ViewType:   ViewTypeStdin,
   558  			},
   559  		},
   560  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   561  			{
   562  				scopeNameTempTables: {
   563  					"STDIN": &View{
   564  						FileInfo: &FileInfo{Path: "STDIN"},
   565  					},
   566  				},
   567  			},
   568  		}, []map[string]map[string]interface{}{
   569  			{
   570  				scopeNameAliases: {
   571  					"T": "STDIN",
   572  				},
   573  			},
   574  		}, time.Time{}, nil),
   575  	},
   576  	{
   577  		Name: "LoadView JsonA From Stdin",
   578  		From: parser.FromClause{
   579  			Tables: []parser.QueryExpression{
   580  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   581  			},
   582  		},
   583  		Stdin:        "[{\"item1\": \"\\u0076\\u0061\\u006c\\u0075\\u0065\\u0031\",\"item2\": 1},{\"item1\": \"\\u0076\\u0061\\u006c\\u0075\\u0065\\u0032\",\"item2\": 2}]",
   584  		ImportFormat: option.JSON,
   585  		JsonQuery:    "{}",
   586  		Result: &View{
   587  			Header: NewHeader("t", []string{"item1", "item2"}),
   588  			RecordSet: []Record{
   589  				NewRecord([]value.Primary{
   590  					value.NewString("value1"),
   591  					value.NewFloat(1),
   592  				}),
   593  				NewRecord([]value.Primary{
   594  					value.NewString("value2"),
   595  					value.NewFloat(2),
   596  				}),
   597  			},
   598  			FileInfo: &FileInfo{
   599  				Path:       "STDIN",
   600  				Delimiter:  ',',
   601  				JsonQuery:  "{}",
   602  				Format:     option.JSON,
   603  				Encoding:   text.UTF8,
   604  				LineBreak:  text.LF,
   605  				JsonEscape: json.AllWithHexDigits,
   606  				ViewType:   ViewTypeStdin,
   607  			},
   608  		},
   609  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   610  			{
   611  				scopeNameTempTables: {
   612  					"STDIN": &View{
   613  						FileInfo: &FileInfo{Path: "STDIN"},
   614  					},
   615  				},
   616  			},
   617  		}, []map[string]map[string]interface{}{
   618  			{
   619  				scopeNameAliases: {
   620  					"T": "STDIN",
   621  				},
   622  			},
   623  		}, time.Time{}, nil),
   624  	},
   625  	{
   626  		Name: "LoadView Json From Stdin Json Query Error",
   627  		From: parser.FromClause{
   628  			Tables: []parser.QueryExpression{
   629  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   630  			},
   631  		},
   632  		Stdin:        "{\"key\":[{\"column1\": 1, \"column2\": \"str1\"}]}",
   633  		ImportFormat: option.JSON,
   634  		JsonQuery:    "key{",
   635  		Error:        "json loading error: column 4: unexpected termination",
   636  	},
   637  	{
   638  		Name:         "LoadView Fixed-Length Text File",
   639  		ImportFormat: option.FIXED,
   640  		From: parser.FromClause{
   641  			Tables: []parser.QueryExpression{
   642  				parser.Table{
   643  					Object: parser.Identifier{Literal: "fixed_length.txt"},
   644  				},
   645  			},
   646  		},
   647  		Result: &View{
   648  			Header: NewHeader("fixed_length", []string{"column1", "__@2__"}),
   649  			RecordSet: []Record{
   650  				NewRecord([]value.Primary{
   651  					value.NewString("1"),
   652  					value.NewString("str1"),
   653  				}),
   654  				NewRecord([]value.Primary{
   655  					value.NewString("2"),
   656  					value.NewString("str2"),
   657  				}),
   658  				NewRecord([]value.Primary{
   659  					value.NewString("3"),
   660  					value.NewString("str3"),
   661  				}),
   662  			},
   663  			FileInfo: &FileInfo{
   664  				Path:               "fixed_length.txt",
   665  				Delimiter:          ',',
   666  				DelimiterPositions: []int{7, 12},
   667  				Format:             option.FIXED,
   668  				NoHeader:           false,
   669  				Encoding:           text.UTF8,
   670  				LineBreak:          text.LF,
   671  			},
   672  		},
   673  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   674  			{scopeNameAliases: {
   675  				"FIXED_LENGTH": strings.ToUpper(GetTestFilePath("fixed_length.txt")),
   676  			}},
   677  		}, time.Time{}, nil),
   678  	},
   679  	{
   680  		Name:         "LoadView Fixed-Length Text File NoHeader",
   681  		NoHeader:     true,
   682  		ImportFormat: option.FIXED,
   683  		From: parser.FromClause{
   684  			Tables: []parser.QueryExpression{
   685  				parser.Table{
   686  					Object: parser.Identifier{Literal: "fixed_length.txt"},
   687  				},
   688  			},
   689  		},
   690  		Result: &View{
   691  			Header: NewHeader("fixed_length", []string{"c1", "c2"}),
   692  			RecordSet: []Record{
   693  				NewRecord([]value.Primary{
   694  					value.NewString("column1"),
   695  					value.NewNull(),
   696  				}),
   697  				NewRecord([]value.Primary{
   698  					value.NewString("1"),
   699  					value.NewString("str1"),
   700  				}),
   701  				NewRecord([]value.Primary{
   702  					value.NewString("2"),
   703  					value.NewString("str2"),
   704  				}),
   705  				NewRecord([]value.Primary{
   706  					value.NewString("3"),
   707  					value.NewString("str3"),
   708  				}),
   709  			},
   710  			FileInfo: &FileInfo{
   711  				Path:               "fixed_length.txt",
   712  				Delimiter:          ',',
   713  				DelimiterPositions: []int{7, 12},
   714  				Format:             option.FIXED,
   715  				NoHeader:           true,
   716  				Encoding:           text.UTF8,
   717  				LineBreak:          text.LF,
   718  			},
   719  		},
   720  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   721  			{scopeNameAliases: {
   722  				"FIXED_LENGTH": strings.ToUpper(GetTestFilePath("fixed_length.txt")),
   723  			}},
   724  		}, time.Time{}, nil),
   725  	},
   726  	{
   727  		Name:               "LoadView Fixed-Length Text File Position Error",
   728  		ImportFormat:       option.FIXED,
   729  		DelimiterPositions: []int{6, 2},
   730  		From: parser.FromClause{
   731  			Tables: []parser.QueryExpression{
   732  				parser.Table{
   733  					Object: parser.Identifier{Literal: "fixed_length.txt"},
   734  				},
   735  			},
   736  		},
   737  		Error: fmt.Sprintf("data parse error in %s: invalid delimiter position: [6, 2]", GetTestFilePath("fixed_length.txt")),
   738  	},
   739  	{
   740  		Name:  "LoadView From Stdin With Omitted FromClause",
   741  		From:  parser.FromClause{},
   742  		Stdin: "column1,column2\n1,\"str1\"",
   743  		Result: &View{
   744  			Header: NewHeader("STDIN", []string{"column1", "column2"}),
   745  			RecordSet: []Record{
   746  				NewRecord([]value.Primary{
   747  					value.NewString("1"),
   748  					value.NewString("str1"),
   749  				}),
   750  			},
   751  			FileInfo: &FileInfo{
   752  				Path:      "STDIN",
   753  				Delimiter: ',',
   754  				Encoding:  text.UTF8,
   755  				LineBreak: text.LF,
   756  				ViewType:  ViewTypeStdin,
   757  			},
   758  		},
   759  		ResultScope: GenerateReferenceScope([]map[string]map[string]interface{}{
   760  			{
   761  				scopeNameTempTables: {
   762  					"STDIN": &View{
   763  						FileInfo: &FileInfo{Path: "STDIN"},
   764  					},
   765  				},
   766  			},
   767  		}, []map[string]map[string]interface{}{
   768  			{
   769  				scopeNameAliases: {
   770  					"STDIN": "STDIN",
   771  				},
   772  			},
   773  		}, time.Time{}, nil),
   774  	},
   775  	{
   776  		Name: "LoadView From Stdin Broken CSV Error",
   777  		From: parser.FromClause{
   778  			Tables: []parser.QueryExpression{
   779  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   780  			},
   781  		},
   782  		Stdin: "column1,column2\n1\"str1\"",
   783  		Error: "data parse error in STDIN: line 1, column 8: wrong number of fields in line",
   784  	},
   785  	{
   786  		Name: "LoadView From Stdin Duplicate Table Name Error",
   787  		From: parser.FromClause{
   788  			Tables: []parser.QueryExpression{
   789  				parser.Table{Object: parser.Identifier{Literal: "table1"}, Alias: parser.Identifier{Literal: "t"}},
   790  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   791  			},
   792  		},
   793  		Stdin: "column1,column2\n1,\"str1\"",
   794  		Error: "table name t is a duplicate",
   795  	},
   796  	{
   797  		Name: "LoadView From Stdin ForUpdate Duplicate Table Name Error",
   798  		From: parser.FromClause{
   799  			Tables: []parser.QueryExpression{
   800  				parser.Table{Object: parser.Identifier{Literal: "table1"}, Alias: parser.Identifier{Literal: "t"}},
   801  				parser.Table{Object: parser.Stdin{}, Alias: parser.Identifier{Literal: "t"}},
   802  			},
   803  		},
   804  		ForUpdate: true,
   805  		Stdin:     "column1,column2\n1,\"str1\"",
   806  		Error:     "table name t is a duplicate",
   807  	},
   808  	{
   809  		Name: "Stdin Empty Error",
   810  		From: parser.FromClause{
   811  			Tables: []parser.QueryExpression{
   812  				parser.Table{
   813  					Object: parser.Stdin{},
   814  				},
   815  			},
   816  		},
   817  		Error: "STDIN is empty",
   818  	},
   819  	{
   820  		Name: "LoadView FormatSpecifiedFunction From CSV File",
   821  		From: parser.FromClause{
   822  			Tables: []parser.QueryExpression{
   823  				parser.Table{
   824  					Object: parser.FormatSpecifiedFunction{
   825  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
   826  						FormatElement: parser.NewStringValue(","),
   827  						Path:          parser.Identifier{Literal: "table5"},
   828  						Args: []parser.QueryExpression{
   829  							parser.NewStringValue("SJIS"),
   830  							parser.NewTernaryValueFromString("true"),
   831  							parser.NewTernaryValueFromString("true"),
   832  						},
   833  					},
   834  					Alias: parser.Identifier{Literal: "t"},
   835  				},
   836  			},
   837  		},
   838  		Result: &View{
   839  			Header: NewHeader("t", []string{"c1", "c2"}),
   840  			RecordSet: []Record{
   841  				NewRecord([]value.Primary{
   842  					value.NewString("1"),
   843  					value.NewString("str1"),
   844  				}),
   845  				NewRecord([]value.Primary{
   846  					value.NewString("2"),
   847  					value.NewString(""),
   848  				}),
   849  				NewRecord([]value.Primary{
   850  					value.NewString("3"),
   851  					value.NewString("str3"),
   852  				}),
   853  			},
   854  			FileInfo: &FileInfo{
   855  				Path:      "table5.csv",
   856  				Delimiter: ',',
   857  				Format:    option.CSV,
   858  				Encoding:  text.SJIS,
   859  				LineBreak: text.LF,
   860  				NoHeader:  true,
   861  			},
   862  		},
   863  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   864  			{scopeNameAliases: {
   865  				"T": strings.ToUpper(GetTestFilePath("table5.csv")),
   866  			}},
   867  		}, time.Time{}, nil),
   868  	},
   869  	{
   870  		Name: "LoadView FormatSpecifiedFunction From TSV File",
   871  		From: parser.FromClause{
   872  			Tables: []parser.QueryExpression{
   873  				parser.Table{
   874  					Object: parser.FormatSpecifiedFunction{
   875  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
   876  						FormatElement: parser.NewStringValue("\t"),
   877  						Path:          parser.Identifier{Literal: "table3"},
   878  						Args: []parser.QueryExpression{
   879  							parser.FieldReference{Column: parser.Identifier{Literal: "UTF8"}},
   880  						},
   881  					},
   882  					Alias: parser.Identifier{Literal: "t"},
   883  				},
   884  			},
   885  		},
   886  		Result: &View{
   887  			Header: NewHeader("t", []string{"column5", "column6"}),
   888  			RecordSet: []Record{
   889  				NewRecord([]value.Primary{
   890  					value.NewString("1"),
   891  					value.NewString("str1"),
   892  				}),
   893  				NewRecord([]value.Primary{
   894  					value.NewString("2"),
   895  					value.NewString("str2"),
   896  				}),
   897  			},
   898  			FileInfo: &FileInfo{
   899  				Path:      "table3.tsv",
   900  				Delimiter: '\t',
   901  				Format:    option.TSV,
   902  				Encoding:  text.UTF8,
   903  				LineBreak: text.LF,
   904  			},
   905  		},
   906  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
   907  			{scopeNameAliases: {
   908  				"T": strings.ToUpper(GetTestFilePath("table3.tsv")),
   909  			}},
   910  		}, time.Time{}, nil),
   911  	},
   912  	{
   913  		Name: "LoadView FormatSpecifiedFunction From CSV File FormatElement Evaluate Error",
   914  		From: parser.FromClause{
   915  			Tables: []parser.QueryExpression{
   916  				parser.Table{
   917  					Object: parser.FormatSpecifiedFunction{
   918  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
   919  						FormatElement: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
   920  						Path:          parser.Identifier{Literal: "table1"},
   921  					},
   922  					Alias: parser.Identifier{Literal: "t"},
   923  				},
   924  			},
   925  		},
   926  		Error: "field notexist does not exist",
   927  	},
   928  	{
   929  		Name: "LoadView FormatSpecifiedFunction From CSV File FormatElement Is Not Specified",
   930  		From: parser.FromClause{
   931  			Tables: []parser.QueryExpression{
   932  				parser.Table{
   933  					Object: parser.FormatSpecifiedFunction{
   934  						Type: parser.Token{Token: parser.CSV, Literal: "csv"},
   935  						Path: parser.Identifier{Literal: "table1"},
   936  					},
   937  					Alias: parser.Identifier{Literal: "t"},
   938  				},
   939  			},
   940  		},
   941  		Error: "invalid argument for csv: delimiter is not specified",
   942  	},
   943  	{
   944  		Name: "LoadView FormatSpecifiedFunction From CSV File FormatElement is Null",
   945  		From: parser.FromClause{
   946  			Tables: []parser.QueryExpression{
   947  				parser.Table{
   948  					Object: parser.FormatSpecifiedFunction{
   949  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
   950  						FormatElement: parser.NewNullValue(),
   951  						Path:          parser.Identifier{Literal: "table1"},
   952  					},
   953  					Alias: parser.Identifier{Literal: "t"},
   954  				},
   955  			},
   956  		},
   957  		Error: "invalid delimiter: NULL",
   958  	},
   959  	{
   960  		Name: "LoadView FormatSpecifiedFunction From CSV File FormatElement Invalid Delimiter",
   961  		From: parser.FromClause{
   962  			Tables: []parser.QueryExpression{
   963  				parser.Table{
   964  					Object: parser.FormatSpecifiedFunction{
   965  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
   966  						FormatElement: parser.NewStringValue("invalid"),
   967  						Path:          parser.Identifier{Literal: "table1"},
   968  					},
   969  					Alias: parser.Identifier{Literal: "t"},
   970  				},
   971  			},
   972  		},
   973  		Error: "invalid delimiter: 'invalid'",
   974  	},
   975  	{
   976  		Name: "LoadView FormatSpecifiedFunction From CSV File Arguments Length Error",
   977  		From: parser.FromClause{
   978  			Tables: []parser.QueryExpression{
   979  				parser.Table{
   980  					Object: parser.FormatSpecifiedFunction{
   981  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
   982  						FormatElement: parser.NewStringValue(","),
   983  						Path:          parser.Identifier{Literal: "table5"},
   984  						Args: []parser.QueryExpression{
   985  							parser.NewStringValue("SJIS"),
   986  							parser.NewTernaryValueFromString("true"),
   987  							parser.NewTernaryValueFromString("true"),
   988  							parser.NewStringValue("extra"),
   989  						},
   990  					},
   991  					Alias: parser.Identifier{Literal: "t"},
   992  				},
   993  			},
   994  		},
   995  		Error: "table object csv takes at most 5 arguments",
   996  	},
   997  	{
   998  		Name: "LoadView FormatSpecifiedFunction From CSV File 3rd Argument Error",
   999  		From: parser.FromClause{
  1000  			Tables: []parser.QueryExpression{
  1001  				parser.Table{
  1002  					Object: parser.FormatSpecifiedFunction{
  1003  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
  1004  						FormatElement: parser.NewStringValue(","),
  1005  						Path:          parser.Identifier{Literal: "table5"},
  1006  						Args: []parser.QueryExpression{
  1007  							parser.NewTernaryValueFromString("true"),
  1008  						},
  1009  					},
  1010  					Alias: parser.Identifier{Literal: "t"},
  1011  				},
  1012  			},
  1013  		},
  1014  		Error: "invalid argument for csv: cannot be converted as a encoding value: TRUE",
  1015  	},
  1016  	{
  1017  		Name: "LoadView FormatSpecifiedFunction From CSV File 4th Argument Error",
  1018  		From: parser.FromClause{
  1019  			Tables: []parser.QueryExpression{
  1020  				parser.Table{
  1021  					Object: parser.FormatSpecifiedFunction{
  1022  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
  1023  						FormatElement: parser.NewStringValue(","),
  1024  						Path:          parser.Identifier{Literal: "table5"},
  1025  						Args: []parser.QueryExpression{
  1026  							parser.NewStringValue("SJIS"),
  1027  							parser.NewStringValue("SJIS"),
  1028  						},
  1029  					},
  1030  					Alias: parser.Identifier{Literal: "t"},
  1031  				},
  1032  			},
  1033  		},
  1034  		Error: "invalid argument for csv: cannot be converted as a no-header value: 'SJIS'",
  1035  	},
  1036  	{
  1037  		Name: "LoadView FormatSpecifiedFunction From CSV File 5th Argument Error",
  1038  		From: parser.FromClause{
  1039  			Tables: []parser.QueryExpression{
  1040  				parser.Table{
  1041  					Object: parser.FormatSpecifiedFunction{
  1042  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
  1043  						FormatElement: parser.NewStringValue(","),
  1044  						Path:          parser.Identifier{Literal: "table5"},
  1045  						Args: []parser.QueryExpression{
  1046  							parser.NewStringValue("SJIS"),
  1047  							parser.NewTernaryValueFromString("true"),
  1048  							parser.NewStringValue("SJIS"),
  1049  						},
  1050  					},
  1051  					Alias: parser.Identifier{Literal: "t"},
  1052  				},
  1053  			},
  1054  		},
  1055  		Error: "invalid argument for csv: cannot be converted as a without-null value: 'SJIS'",
  1056  	},
  1057  	{
  1058  		Name: "LoadView FormatSpecifiedFunction From CSV File Invalid Encoding Type",
  1059  		From: parser.FromClause{
  1060  			Tables: []parser.QueryExpression{
  1061  				parser.Table{
  1062  					Object: parser.FormatSpecifiedFunction{
  1063  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
  1064  						FormatElement: parser.NewStringValue(","),
  1065  						Path:          parser.Identifier{Literal: "table5"},
  1066  						Args: []parser.QueryExpression{
  1067  							parser.NewStringValue("INVALID"),
  1068  						},
  1069  					},
  1070  					Alias: parser.Identifier{Literal: "t"},
  1071  				},
  1072  			},
  1073  		},
  1074  		Error: "invalid argument for csv: encoding must be one of AUTO|UTF8|UTF8M|UTF16|UTF16BE|UTF16LE|UTF16BEM|UTF16LEM|SJIS",
  1075  	},
  1076  	{
  1077  		Name: "LoadView FormatSpecifiedFunction From Fixed-Length File",
  1078  		From: parser.FromClause{
  1079  			Tables: []parser.QueryExpression{
  1080  				parser.Table{
  1081  					Object: parser.FormatSpecifiedFunction{
  1082  						Type:          parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1083  						FormatElement: parser.NewStringValue("spaces"),
  1084  						Path:          parser.Identifier{Literal: "fixed_length.txt", Quoted: true},
  1085  					},
  1086  					Alias: parser.Identifier{Literal: "t"},
  1087  				},
  1088  			},
  1089  		},
  1090  		Result: &View{
  1091  			Header: NewHeader("t", []string{"column1", "__@2__"}),
  1092  			RecordSet: []Record{
  1093  				NewRecord([]value.Primary{
  1094  					value.NewString("1"),
  1095  					value.NewString("str1"),
  1096  				}),
  1097  				NewRecord([]value.Primary{
  1098  					value.NewString("2"),
  1099  					value.NewString("str2"),
  1100  				}),
  1101  				NewRecord([]value.Primary{
  1102  					value.NewString("3"),
  1103  					value.NewString("str3"),
  1104  				}),
  1105  			},
  1106  			FileInfo: &FileInfo{
  1107  				Path:               "fixed_length.txt",
  1108  				Delimiter:          ',',
  1109  				DelimiterPositions: []int{7, 12},
  1110  				Format:             option.FIXED,
  1111  				Encoding:           text.UTF8,
  1112  				LineBreak:          text.LF,
  1113  			},
  1114  		},
  1115  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1116  			{scopeNameAliases: {
  1117  				"T": strings.ToUpper(GetTestFilePath("fixed_length.txt")),
  1118  			}},
  1119  		}, time.Time{}, nil),
  1120  	},
  1121  	{
  1122  		Name: "LoadView FormatSpecifiedFunction From Fixed-Length File with UTF-8 BOM",
  1123  		From: parser.FromClause{
  1124  			Tables: []parser.QueryExpression{
  1125  				parser.Table{
  1126  					Object: parser.FormatSpecifiedFunction{
  1127  						Type:          parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1128  						FormatElement: parser.NewStringValue("spaces"),
  1129  						Path:          parser.Identifier{Literal: "fixed_length_bom.txt", Quoted: true},
  1130  					},
  1131  					Alias: parser.Identifier{Literal: "t"},
  1132  				},
  1133  			},
  1134  		},
  1135  		Result: &View{
  1136  			Header: NewHeader("t", []string{"column1", "__@2__"}),
  1137  			RecordSet: []Record{
  1138  				NewRecord([]value.Primary{
  1139  					value.NewString("1"),
  1140  					value.NewString("str1"),
  1141  				}),
  1142  				NewRecord([]value.Primary{
  1143  					value.NewString("2"),
  1144  					value.NewString("str2"),
  1145  				}),
  1146  				NewRecord([]value.Primary{
  1147  					value.NewString("3"),
  1148  					value.NewString("str3"),
  1149  				}),
  1150  			},
  1151  			FileInfo: &FileInfo{
  1152  				Path:               "fixed_length_bom.txt",
  1153  				Delimiter:          ',',
  1154  				DelimiterPositions: []int{7, 12},
  1155  				Format:             option.FIXED,
  1156  				Encoding:           text.UTF8M,
  1157  				LineBreak:          text.LF,
  1158  			},
  1159  		},
  1160  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1161  			{scopeNameAliases: {
  1162  				"T": strings.ToUpper(GetTestFilePath("fixed_length_bom.txt")),
  1163  			}},
  1164  		}, time.Time{}, nil),
  1165  	},
  1166  	{
  1167  		Name: "LoadView FormatSpecifiedFunction From Single-Line Fixed-Length File",
  1168  		From: parser.FromClause{
  1169  			Tables: []parser.QueryExpression{
  1170  				parser.Table{
  1171  					Object: parser.FormatSpecifiedFunction{
  1172  						Type:          parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1173  						FormatElement: parser.NewStringValue("s[1,5]"),
  1174  						Path:          parser.Identifier{Literal: "fixed_length_sl.txt", Quoted: true},
  1175  					},
  1176  					Alias: parser.Identifier{Literal: "t"},
  1177  				},
  1178  			},
  1179  		},
  1180  		Result: &View{
  1181  			Header: NewHeader("t", []string{"c1", "c2"}),
  1182  			RecordSet: []Record{
  1183  				NewRecord([]value.Primary{
  1184  					value.NewString("1"),
  1185  					value.NewString("str1"),
  1186  				}),
  1187  				NewRecord([]value.Primary{
  1188  					value.NewString("2"),
  1189  					value.NewString("str2"),
  1190  				}),
  1191  				NewRecord([]value.Primary{
  1192  					value.NewString("3"),
  1193  					value.NewString("str3"),
  1194  				}),
  1195  			},
  1196  			FileInfo: &FileInfo{
  1197  				Path:               "fixed_length_sl.txt",
  1198  				Delimiter:          ',',
  1199  				DelimiterPositions: []int{1, 5},
  1200  				Format:             option.FIXED,
  1201  				Encoding:           text.UTF8,
  1202  				LineBreak:          text.LF,
  1203  				SingleLine:         true,
  1204  			},
  1205  		},
  1206  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1207  			{scopeNameAliases: {
  1208  				"T": strings.ToUpper(GetTestFilePath("fixed_length_sl.txt")),
  1209  			}},
  1210  		}, time.Time{}, nil),
  1211  	},
  1212  	{
  1213  		Name: "LoadView FormatSpecifiedFunction From Fixed-Length File FormatElement Is Not Specified",
  1214  		From: parser.FromClause{
  1215  			Tables: []parser.QueryExpression{
  1216  				parser.Table{
  1217  					Object: parser.FormatSpecifiedFunction{
  1218  						Type: parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1219  						Path: parser.Identifier{Literal: "fixed_length.txt", Quoted: true},
  1220  					},
  1221  					Alias: parser.Identifier{Literal: "t"},
  1222  				},
  1223  			},
  1224  		},
  1225  		Error: "invalid argument for fixed: delimiter positions are not specified",
  1226  	},
  1227  	{
  1228  		Name: "LoadView FormatSpecifiedFunction From Fixed-Length File FormatElement is Null",
  1229  		From: parser.FromClause{
  1230  			Tables: []parser.QueryExpression{
  1231  				parser.Table{
  1232  					Object: parser.FormatSpecifiedFunction{
  1233  						Type:          parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1234  						FormatElement: parser.NewNullValue(),
  1235  						Path:          parser.Identifier{Literal: "fixed_length.txt", Quoted: true},
  1236  					},
  1237  					Alias: parser.Identifier{Literal: "t"},
  1238  				},
  1239  			},
  1240  		},
  1241  		Error: "invalid delimiter positions: NULL",
  1242  	},
  1243  	{
  1244  		Name: "LoadView FormatSpecifiedFunction From Fixed-Length File Invalid Delimiter Positions",
  1245  		From: parser.FromClause{
  1246  			Tables: []parser.QueryExpression{
  1247  				parser.Table{
  1248  					Object: parser.FormatSpecifiedFunction{
  1249  						Type:          parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1250  						FormatElement: parser.NewStringValue("invalid"),
  1251  						Path:          parser.Identifier{Literal: "fixed_length.txt", Quoted: true},
  1252  					},
  1253  					Alias: parser.Identifier{Literal: "t"},
  1254  				},
  1255  			},
  1256  		},
  1257  		Error: "invalid delimiter positions: 'invalid'",
  1258  	},
  1259  	{
  1260  		Name: "LoadView FormatSpecifiedFunction From Fixed-Length File Arguments Length Error",
  1261  		From: parser.FromClause{
  1262  			Tables: []parser.QueryExpression{
  1263  				parser.Table{
  1264  					Object: parser.FormatSpecifiedFunction{
  1265  						Type:          parser.Token{Token: parser.FIXED, Literal: "fixed"},
  1266  						FormatElement: parser.NewStringValue("spaces"),
  1267  						Path:          parser.Identifier{Literal: "fixed_length.txt", Quoted: true},
  1268  						Args: []parser.QueryExpression{
  1269  							parser.NewStringValue("SJIS"),
  1270  							parser.NewTernaryValueFromString("true"),
  1271  							parser.NewTernaryValueFromString("true"),
  1272  							parser.NewStringValue("extra"),
  1273  						},
  1274  					},
  1275  					Alias: parser.Identifier{Literal: "t"},
  1276  				},
  1277  			},
  1278  		},
  1279  		Error: "table object fixed takes at most 5 arguments",
  1280  	},
  1281  	{
  1282  		Name: "LoadView FormatSpecifiedFunction From Json File",
  1283  		From: parser.FromClause{
  1284  			Tables: []parser.QueryExpression{
  1285  				parser.Table{
  1286  					Object: parser.FormatSpecifiedFunction{
  1287  						Type:          parser.Token{Token: parser.JSON, Literal: "json"},
  1288  						FormatElement: parser.NewStringValue("{}"),
  1289  						Path:          parser.Identifier{Literal: "table"},
  1290  					},
  1291  					Alias: parser.Identifier{Literal: "jt"},
  1292  				},
  1293  			},
  1294  		},
  1295  		Result: &View{
  1296  			Header: NewHeader("jt", []string{"item1", "item2"}),
  1297  			RecordSet: []Record{
  1298  				NewRecord([]value.Primary{
  1299  					value.NewString("value1"),
  1300  					value.NewFloat(1),
  1301  				}),
  1302  				NewRecord([]value.Primary{
  1303  					value.NewString("value2"),
  1304  					value.NewFloat(2),
  1305  				}),
  1306  			},
  1307  			FileInfo: &FileInfo{
  1308  				Path:      "table.json",
  1309  				Delimiter: ',',
  1310  				JsonQuery: "{}",
  1311  				Format:    option.JSON,
  1312  				Encoding:  text.UTF8,
  1313  				LineBreak: text.LF,
  1314  			},
  1315  		},
  1316  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1317  			{scopeNameAliases: {
  1318  				"JT": strings.ToUpper(GetTestFilePath("table.json")),
  1319  			}},
  1320  		}, time.Time{}, nil),
  1321  	},
  1322  	{
  1323  		Name: "LoadView FormatSpecifiedFunction From JsonH File",
  1324  		From: parser.FromClause{
  1325  			Tables: []parser.QueryExpression{
  1326  				parser.Table{
  1327  					Object: parser.FormatSpecifiedFunction{
  1328  						Type:          parser.Token{Token: parser.JSON, Literal: "json"},
  1329  						FormatElement: parser.NewStringValue("{}"),
  1330  						Path:          parser.Identifier{Literal: "table_h"},
  1331  					},
  1332  					Alias: parser.Identifier{Literal: "jt"},
  1333  				},
  1334  			},
  1335  		},
  1336  		Result: &View{
  1337  			Header: NewHeader("jt", []string{"item1", "item2"}),
  1338  			RecordSet: []Record{
  1339  				NewRecord([]value.Primary{
  1340  					value.NewString("value\"1"),
  1341  					value.NewFloat(1),
  1342  				}),
  1343  				NewRecord([]value.Primary{
  1344  					value.NewString("value2"),
  1345  					value.NewFloat(2),
  1346  				}),
  1347  			},
  1348  			FileInfo: &FileInfo{
  1349  				Path:       "table_h.json",
  1350  				Delimiter:  ',',
  1351  				JsonQuery:  "{}",
  1352  				Format:     option.JSON,
  1353  				Encoding:   text.UTF8,
  1354  				LineBreak:  text.LF,
  1355  				JsonEscape: json.HexDigits,
  1356  			},
  1357  		},
  1358  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1359  			{scopeNameAliases: {
  1360  				"JT": strings.ToUpper(GetTestFilePath("table_h.json")),
  1361  			}},
  1362  		}, time.Time{}, nil),
  1363  	},
  1364  	{
  1365  		Name: "LoadView FormatSpecifiedFunction From JsonA File",
  1366  		From: parser.FromClause{
  1367  			Tables: []parser.QueryExpression{
  1368  				parser.Table{
  1369  					Object: parser.FormatSpecifiedFunction{
  1370  						Type:          parser.Token{Token: parser.JSON, Literal: "json"},
  1371  						FormatElement: parser.NewStringValue("{}"),
  1372  						Path:          parser.Identifier{Literal: "table_a"},
  1373  					},
  1374  					Alias: parser.Identifier{Literal: "jt"},
  1375  				},
  1376  			},
  1377  		},
  1378  		Result: &View{
  1379  			Header: NewHeader("jt", []string{"item1", "item2"}),
  1380  			RecordSet: []Record{
  1381  				NewRecord([]value.Primary{
  1382  					value.NewString("value1"),
  1383  					value.NewFloat(1),
  1384  				}),
  1385  				NewRecord([]value.Primary{
  1386  					value.NewString("value2"),
  1387  					value.NewFloat(2),
  1388  				}),
  1389  			},
  1390  			FileInfo: &FileInfo{
  1391  				Path:       "table_a.json",
  1392  				Delimiter:  ',',
  1393  				JsonQuery:  "{}",
  1394  				Format:     option.JSON,
  1395  				Encoding:   text.UTF8,
  1396  				LineBreak:  text.LF,
  1397  				JsonEscape: json.AllWithHexDigits,
  1398  			},
  1399  		},
  1400  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1401  			{scopeNameAliases: {
  1402  				"JT": strings.ToUpper(GetTestFilePath("table_a.json")),
  1403  			}},
  1404  		}, time.Time{}, nil),
  1405  	},
  1406  	{
  1407  		Name: "LoadView FormatSpecifiedFunction From Json File FormatElement Is Not Specified",
  1408  		From: parser.FromClause{
  1409  			Tables: []parser.QueryExpression{
  1410  				parser.Table{
  1411  					Object: parser.FormatSpecifiedFunction{
  1412  						Type: parser.Token{Token: parser.JSON, Literal: "json"},
  1413  						Path: parser.Identifier{Literal: "table"},
  1414  					},
  1415  					Alias: parser.Identifier{Literal: "jt"},
  1416  				},
  1417  			},
  1418  		},
  1419  		Error: "invalid argument for json: json query is not specified",
  1420  	},
  1421  	{
  1422  		Name: "LoadView FormatSpecifiedFunction From Json File FormatElement is Null",
  1423  		From: parser.FromClause{
  1424  			Tables: []parser.QueryExpression{
  1425  				parser.Table{
  1426  					Object: parser.FormatSpecifiedFunction{
  1427  						Type:          parser.Token{Token: parser.JSON, Literal: "json"},
  1428  						FormatElement: parser.NewNullValue(),
  1429  						Path:          parser.Identifier{Literal: "table"},
  1430  					},
  1431  					Alias: parser.Identifier{Literal: "jt"},
  1432  				},
  1433  			},
  1434  		},
  1435  		Error: "invalid json query: NULL",
  1436  	},
  1437  	{
  1438  		Name: "LoadView Table Object From Json File Path Error",
  1439  		From: parser.FromClause{
  1440  			Tables: []parser.QueryExpression{
  1441  				parser.Table{
  1442  					Object: parser.FormatSpecifiedFunction{
  1443  						Type:          parser.Token{Token: parser.JSON, Literal: "json"},
  1444  						FormatElement: parser.NewStringValue("{}"),
  1445  						Path:          parser.Identifier{Literal: "notexist"},
  1446  					},
  1447  					Alias: parser.Identifier{Literal: "jt"},
  1448  				},
  1449  			},
  1450  		},
  1451  		Error: "file notexist does not exist",
  1452  	},
  1453  	{
  1454  		Name: "LoadView FormatSpecifiedFunction From Json Lines File",
  1455  		From: parser.FromClause{
  1456  			Tables: []parser.QueryExpression{
  1457  				parser.Table{
  1458  					Object: parser.FormatSpecifiedFunction{
  1459  						Type:          parser.Token{Token: parser.JSONL, Literal: "jsonl"},
  1460  						FormatElement: parser.NewStringValue("{}"),
  1461  						Path:          parser.Identifier{Literal: "table7"},
  1462  					},
  1463  					Alias: parser.Identifier{Literal: "jt"},
  1464  				},
  1465  			},
  1466  		},
  1467  		Result: &View{
  1468  			Header: NewHeader("jt", []string{"item1", "item2"}),
  1469  			RecordSet: []Record{
  1470  				NewRecord([]value.Primary{
  1471  					value.NewString("value1"),
  1472  					value.NewFloat(1),
  1473  				}),
  1474  				NewRecord([]value.Primary{
  1475  					value.NewString("value2"),
  1476  					value.NewFloat(2),
  1477  				}),
  1478  			},
  1479  			FileInfo: &FileInfo{
  1480  				Path:      "table7.jsonl",
  1481  				Delimiter: ',',
  1482  				JsonQuery: "{}",
  1483  				Format:    option.JSONL,
  1484  				Encoding:  text.UTF8,
  1485  				LineBreak: text.LF,
  1486  			},
  1487  		},
  1488  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1489  			{scopeNameAliases: {
  1490  				"JT": strings.ToUpper(GetTestFilePath("table7.jsonl")),
  1491  			}},
  1492  		}, time.Time{}, nil),
  1493  	},
  1494  	{
  1495  		Name: "LoadView FormatSpecifiedFunction From LTSV File",
  1496  		From: parser.FromClause{
  1497  			Tables: []parser.QueryExpression{
  1498  				parser.Table{
  1499  					Object: parser.FormatSpecifiedFunction{
  1500  						Type: parser.Token{Token: parser.LTSV, Literal: "ltsv"},
  1501  						Path: parser.Identifier{Literal: "table6"},
  1502  					},
  1503  					Alias: parser.Identifier{Literal: "t"},
  1504  				},
  1505  			},
  1506  		},
  1507  		Result: &View{
  1508  			Header: NewHeader("t", []string{"f1", "f2", "f3", "f4"}),
  1509  			RecordSet: []Record{
  1510  				NewRecord([]value.Primary{
  1511  					value.NewString("value1"),
  1512  					value.NewString("value2"),
  1513  					value.NewString("value3"),
  1514  					value.NewNull(),
  1515  				}),
  1516  				NewRecord([]value.Primary{
  1517  					value.NewString("value4"),
  1518  					value.NewString("value5"),
  1519  					value.NewNull(),
  1520  					value.NewString("value6"),
  1521  				}),
  1522  			},
  1523  			FileInfo: &FileInfo{
  1524  				Path:      "table6.ltsv",
  1525  				Delimiter: ',',
  1526  				Format:    option.LTSV,
  1527  				Encoding:  text.UTF8,
  1528  				LineBreak: text.LF,
  1529  			},
  1530  		},
  1531  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1532  			{scopeNameAliases: {
  1533  				"T": strings.ToUpper(GetTestFilePath("table6.ltsv")),
  1534  			}},
  1535  		}, time.Time{}, nil),
  1536  	},
  1537  	{
  1538  		Name: "LoadView FormatSpecifiedFunction From LTSV File Without Null",
  1539  		From: parser.FromClause{
  1540  			Tables: []parser.QueryExpression{
  1541  				parser.Table{
  1542  					Object: parser.FormatSpecifiedFunction{
  1543  						Type: parser.Token{Token: parser.LTSV, Literal: "ltsv"},
  1544  						Path: parser.Identifier{Literal: "table6"},
  1545  						Args: []parser.QueryExpression{
  1546  							parser.NewStringValue("UTF8"),
  1547  							parser.NewTernaryValueFromString("true"),
  1548  						},
  1549  					},
  1550  					Alias: parser.Identifier{Literal: "t"},
  1551  				},
  1552  			},
  1553  		},
  1554  		Result: &View{
  1555  			Header: NewHeader("t", []string{"f1", "f2", "f3", "f4"}),
  1556  			RecordSet: []Record{
  1557  				NewRecord([]value.Primary{
  1558  					value.NewString("value1"),
  1559  					value.NewString("value2"),
  1560  					value.NewString("value3"),
  1561  					value.NewString(""),
  1562  				}),
  1563  				NewRecord([]value.Primary{
  1564  					value.NewString("value4"),
  1565  					value.NewString("value5"),
  1566  					value.NewString(""),
  1567  					value.NewString("value6"),
  1568  				}),
  1569  			},
  1570  			FileInfo: &FileInfo{
  1571  				Path:      "table6.ltsv",
  1572  				Delimiter: ',',
  1573  				Format:    option.LTSV,
  1574  				Encoding:  text.UTF8,
  1575  				LineBreak: text.LF,
  1576  			},
  1577  		},
  1578  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1579  			{scopeNameAliases: {
  1580  				"T": strings.ToUpper(GetTestFilePath("table6.ltsv")),
  1581  			}},
  1582  		}, time.Time{}, nil),
  1583  	},
  1584  	{
  1585  		Name: "LoadView FormatSpecifiedFunction From LTSV File with UTF-8 BOM",
  1586  		From: parser.FromClause{
  1587  			Tables: []parser.QueryExpression{
  1588  				parser.Table{
  1589  					Object: parser.FormatSpecifiedFunction{
  1590  						Type: parser.Token{Token: parser.LTSV, Literal: "ltsv"},
  1591  						Path: parser.Identifier{Literal: "table6_bom"},
  1592  					},
  1593  					Alias: parser.Identifier{Literal: "t"},
  1594  				},
  1595  			},
  1596  		},
  1597  		Result: &View{
  1598  			Header: NewHeader("t", []string{"f1", "f2", "f3", "f4"}),
  1599  			RecordSet: []Record{
  1600  				NewRecord([]value.Primary{
  1601  					value.NewString("value1"),
  1602  					value.NewString("value2"),
  1603  					value.NewString("value3"),
  1604  					value.NewNull(),
  1605  				}),
  1606  				NewRecord([]value.Primary{
  1607  					value.NewString("value4"),
  1608  					value.NewString("value5"),
  1609  					value.NewNull(),
  1610  					value.NewString("value6"),
  1611  				}),
  1612  			},
  1613  			FileInfo: &FileInfo{
  1614  				Path:      "table6_bom.ltsv",
  1615  				Delimiter: ',',
  1616  				Format:    option.LTSV,
  1617  				Encoding:  text.UTF8M,
  1618  				LineBreak: text.LF,
  1619  			},
  1620  		},
  1621  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1622  			{scopeNameAliases: {
  1623  				"T": strings.ToUpper(GetTestFilePath("table6_bom.ltsv")),
  1624  			}},
  1625  		}, time.Time{}, nil),
  1626  	},
  1627  	{
  1628  		Name: "LoadView FormatSpecifiedFunction From LTSV File Arguments Length Error",
  1629  		From: parser.FromClause{
  1630  			Tables: []parser.QueryExpression{
  1631  				parser.Table{
  1632  					Object: parser.FormatSpecifiedFunction{
  1633  						Type: parser.Token{Token: parser.LTSV, Literal: "ltsv"},
  1634  						Path: parser.Identifier{Literal: "table6"},
  1635  						Args: []parser.QueryExpression{
  1636  							parser.NewStringValue("UTF8"),
  1637  							parser.NewTernaryValueFromString("true"),
  1638  							parser.NewStringValue("extra"),
  1639  						},
  1640  					},
  1641  					Alias: parser.Identifier{Literal: "t"},
  1642  				},
  1643  			},
  1644  		},
  1645  		Error: "table object ltsv takes exactly 3 arguments",
  1646  	},
  1647  	{
  1648  		Name: "LoadView FormatSpecifiedFunction Invalid Object Type",
  1649  		From: parser.FromClause{
  1650  			Tables: []parser.QueryExpression{
  1651  				parser.Table{
  1652  					Object: parser.FormatSpecifiedFunction{
  1653  						Type:          parser.Token{Token: 0, Literal: "invalid"},
  1654  						FormatElement: parser.NewStringValue(","),
  1655  						Path:          parser.Identifier{Literal: "table"},
  1656  					},
  1657  					Alias: parser.Identifier{Literal: "jt"},
  1658  				},
  1659  			},
  1660  		},
  1661  		Error: "invalid table object: invalid",
  1662  	},
  1663  	{
  1664  		Name: "LoadView FormatSpecifiedFunction From Json File Arguments Length Error",
  1665  		From: parser.FromClause{
  1666  			Tables: []parser.QueryExpression{
  1667  				parser.Table{
  1668  					Object: parser.FormatSpecifiedFunction{
  1669  						Type:          parser.Token{Token: parser.JSON, Literal: "json"},
  1670  						FormatElement: parser.NewStringValue("{}"),
  1671  						Path:          parser.Identifier{Literal: "table"},
  1672  						Args: []parser.QueryExpression{
  1673  							parser.NewStringValue("SJIS"),
  1674  						},
  1675  					},
  1676  					Alias: parser.Identifier{Literal: "jt"},
  1677  				},
  1678  			},
  1679  		},
  1680  		Error: "table object json takes exactly 2 arguments",
  1681  	},
  1682  	{
  1683  		Name: "LoadView File Error",
  1684  		From: parser.FromClause{
  1685  			Tables: []parser.QueryExpression{
  1686  				parser.Table{
  1687  					Object: parser.Identifier{Literal: "notexist"},
  1688  				},
  1689  			},
  1690  		},
  1691  		Error: "file notexist does not exist",
  1692  	},
  1693  	{
  1694  		Name: "LoadView From File Duplicate Table Name Error",
  1695  		From: parser.FromClause{
  1696  			Tables: []parser.QueryExpression{
  1697  				parser.Table{Object: parser.Identifier{Literal: "table1"}, Alias: parser.Identifier{Literal: "t"}},
  1698  				parser.Table{Object: parser.Identifier{Literal: "table2"}, Alias: parser.Identifier{Literal: "t"}},
  1699  			},
  1700  		},
  1701  		Error: "table name t is a duplicate",
  1702  	},
  1703  	{
  1704  		Name: "LoadView From File ForUpdate Duplicate Table Name Error",
  1705  		From: parser.FromClause{
  1706  			Tables: []parser.QueryExpression{
  1707  				parser.Table{Object: parser.Identifier{Literal: "table1"}, Alias: parser.Identifier{Literal: "t"}},
  1708  				parser.Table{Object: parser.Identifier{Literal: "table2"}, Alias: parser.Identifier{Literal: "t"}},
  1709  			},
  1710  		},
  1711  		ForUpdate: true,
  1712  		Error:     "table name t is a duplicate",
  1713  	},
  1714  	{
  1715  		Name: "LoadView From File Inline Table",
  1716  		From: parser.FromClause{
  1717  			Tables: []parser.QueryExpression{
  1718  				parser.Table{Object: parser.Identifier{Literal: "it"}, Alias: parser.Identifier{Literal: "t"}},
  1719  			},
  1720  		},
  1721  		Scope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1722  			{
  1723  				scopeNameInlineTables: {
  1724  					"IT": &View{
  1725  						Header: NewHeader("it", []string{"c1", "c2", "num"}),
  1726  						RecordSet: []Record{
  1727  							NewRecord([]value.Primary{
  1728  								value.NewString("1"),
  1729  								value.NewString("str1"),
  1730  								value.NewInteger(1),
  1731  							}),
  1732  							NewRecord([]value.Primary{
  1733  								value.NewString("2"),
  1734  								value.NewString("str2"),
  1735  								value.NewInteger(1),
  1736  							}),
  1737  							NewRecord([]value.Primary{
  1738  								value.NewString("3"),
  1739  								value.NewString("str3"),
  1740  								value.NewInteger(1),
  1741  							}),
  1742  						},
  1743  					},
  1744  				},
  1745  			},
  1746  		}, time.Time{}, nil),
  1747  		Result: &View{
  1748  			Header: NewHeader("t", []string{"c1", "c2", "num"}),
  1749  			RecordSet: []Record{
  1750  				NewRecord([]value.Primary{
  1751  					value.NewString("1"),
  1752  					value.NewString("str1"),
  1753  					value.NewInteger(1),
  1754  				}),
  1755  				NewRecord([]value.Primary{
  1756  					value.NewString("2"),
  1757  					value.NewString("str2"),
  1758  					value.NewInteger(1),
  1759  				}),
  1760  				NewRecord([]value.Primary{
  1761  					value.NewString("3"),
  1762  					value.NewString("str3"),
  1763  					value.NewInteger(1),
  1764  				}),
  1765  			},
  1766  		},
  1767  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1768  			{
  1769  				scopeNameAliases: {
  1770  					"T": "",
  1771  				},
  1772  			},
  1773  			{
  1774  				scopeNameInlineTables: {
  1775  					"IT": &View{
  1776  						Header: NewHeader("it", []string{"c1", "c2", "num"}),
  1777  						RecordSet: []Record{
  1778  							NewRecord([]value.Primary{
  1779  								value.NewString("1"),
  1780  								value.NewString("str1"),
  1781  								value.NewInteger(1),
  1782  							}),
  1783  							NewRecord([]value.Primary{
  1784  								value.NewString("2"),
  1785  								value.NewString("str2"),
  1786  								value.NewInteger(1),
  1787  							}),
  1788  							NewRecord([]value.Primary{
  1789  								value.NewString("3"),
  1790  								value.NewString("str3"),
  1791  								value.NewInteger(1),
  1792  							}),
  1793  						},
  1794  					},
  1795  				},
  1796  			},
  1797  		}, time.Time{}, nil),
  1798  	},
  1799  	{
  1800  		Name: "LoadView From File Inline Table Duplicate Table Name Error",
  1801  		From: parser.FromClause{
  1802  			Tables: []parser.QueryExpression{
  1803  				parser.Table{Object: parser.Identifier{Literal: "table1"}, Alias: parser.Identifier{Literal: "t"}},
  1804  				parser.Table{Object: parser.Identifier{Literal: "it"}, Alias: parser.Identifier{Literal: "t"}},
  1805  			},
  1806  		},
  1807  		Scope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1808  			{
  1809  				scopeNameInlineTables: {
  1810  					"IT": &View{
  1811  						Header: NewHeader("it", []string{"c1", "c2", "num"}),
  1812  						RecordSet: []Record{
  1813  							NewRecord([]value.Primary{
  1814  								value.NewString("1"),
  1815  								value.NewString("str1"),
  1816  								value.NewInteger(1),
  1817  							}),
  1818  							NewRecord([]value.Primary{
  1819  								value.NewString("2"),
  1820  								value.NewString("str2"),
  1821  								value.NewInteger(1),
  1822  							}),
  1823  							NewRecord([]value.Primary{
  1824  								value.NewString("3"),
  1825  								value.NewString("str3"),
  1826  								value.NewInteger(1),
  1827  							}),
  1828  						},
  1829  					},
  1830  				},
  1831  			},
  1832  		}, time.Time{}, nil),
  1833  		Error: "table name t is a duplicate",
  1834  	},
  1835  	{
  1836  		Name:     "LoadView SJIS File",
  1837  		Encoding: text.SJIS,
  1838  		From: parser.FromClause{
  1839  			Tables: []parser.QueryExpression{
  1840  				parser.Table{
  1841  					Object: parser.Identifier{Literal: "table_sjis"},
  1842  				},
  1843  			},
  1844  		},
  1845  		Result: &View{
  1846  			Header: NewHeader("table_sjis", []string{"column1", "column2"}),
  1847  			RecordSet: []Record{
  1848  				NewRecord([]value.Primary{
  1849  					value.NewString("1"),
  1850  					value.NewString("日本語"),
  1851  				}),
  1852  				NewRecord([]value.Primary{
  1853  					value.NewString("2"),
  1854  					value.NewString("str"),
  1855  				}),
  1856  			},
  1857  		},
  1858  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1859  			{scopeNameAliases: {
  1860  				"TABLE_SJIS": strings.ToUpper(GetTestFilePath("table_sjis.csv")),
  1861  			}},
  1862  		}, time.Time{}, nil),
  1863  	},
  1864  	{
  1865  		Name:     "LoadView No Header File",
  1866  		NoHeader: true,
  1867  		From: parser.FromClause{
  1868  			Tables: []parser.QueryExpression{
  1869  				parser.Table{
  1870  					Object: parser.Identifier{Literal: "table_noheader"},
  1871  				},
  1872  			},
  1873  		},
  1874  		Result: &View{
  1875  			Header: NewHeader("table_noheader", []string{"c1", "c2"}),
  1876  			RecordSet: []Record{
  1877  				NewRecord([]value.Primary{
  1878  					value.NewString("1"),
  1879  					value.NewString("str1"),
  1880  				}),
  1881  				NewRecord([]value.Primary{
  1882  					value.NewString("2"),
  1883  					value.NewString("str2"),
  1884  				}),
  1885  			},
  1886  		},
  1887  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1888  			{scopeNameAliases: {
  1889  				"TABLE_NOHEADER": strings.ToUpper(GetTestFilePath("table_noheader.csv")),
  1890  			}},
  1891  		}, time.Time{}, nil),
  1892  	},
  1893  	{
  1894  		Name: "LoadView Multiple File",
  1895  		From: parser.FromClause{
  1896  			Tables: []parser.QueryExpression{
  1897  				parser.Table{
  1898  					Object: parser.Identifier{Literal: "table1"},
  1899  				},
  1900  				parser.Table{
  1901  					Object: parser.Identifier{Literal: "table2"},
  1902  				},
  1903  			},
  1904  		},
  1905  		Result: &View{
  1906  			Header: []HeaderField{
  1907  				{View: "table1", Column: "column1", Number: 1, IsFromTable: true},
  1908  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  1909  				{View: "table2", Column: "column3", Number: 1, IsFromTable: true},
  1910  				{View: "table2", Column: "column4", Number: 2, IsFromTable: true},
  1911  			},
  1912  			RecordSet: []Record{
  1913  				NewRecord([]value.Primary{
  1914  					value.NewString("1"),
  1915  					value.NewString("str1"),
  1916  					value.NewString("2"),
  1917  					value.NewString("str22"),
  1918  				}),
  1919  				NewRecord([]value.Primary{
  1920  					value.NewString("1"),
  1921  					value.NewString("str1"),
  1922  					value.NewString("3"),
  1923  					value.NewString("str33"),
  1924  				}),
  1925  				NewRecord([]value.Primary{
  1926  					value.NewString("1"),
  1927  					value.NewString("str1"),
  1928  					value.NewString("4"),
  1929  					value.NewString("str44"),
  1930  				}),
  1931  				NewRecord([]value.Primary{
  1932  					value.NewString("2"),
  1933  					value.NewString("str2"),
  1934  					value.NewString("2"),
  1935  					value.NewString("str22"),
  1936  				}),
  1937  				NewRecord([]value.Primary{
  1938  					value.NewString("2"),
  1939  					value.NewString("str2"),
  1940  					value.NewString("3"),
  1941  					value.NewString("str33"),
  1942  				}),
  1943  				NewRecord([]value.Primary{
  1944  					value.NewString("2"),
  1945  					value.NewString("str2"),
  1946  					value.NewString("4"),
  1947  					value.NewString("str44"),
  1948  				}),
  1949  				NewRecord([]value.Primary{
  1950  					value.NewString("3"),
  1951  					value.NewString("str3"),
  1952  					value.NewString("2"),
  1953  					value.NewString("str22"),
  1954  				}),
  1955  				NewRecord([]value.Primary{
  1956  					value.NewString("3"),
  1957  					value.NewString("str3"),
  1958  					value.NewString("3"),
  1959  					value.NewString("str33"),
  1960  				}),
  1961  				NewRecord([]value.Primary{
  1962  					value.NewString("3"),
  1963  					value.NewString("str3"),
  1964  					value.NewString("4"),
  1965  					value.NewString("str44"),
  1966  				}),
  1967  			},
  1968  		},
  1969  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  1970  			{scopeNameAliases: {
  1971  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
  1972  				"TABLE2": strings.ToUpper(GetTestFilePath("table2.csv")),
  1973  			}},
  1974  		}, time.Time{}, nil),
  1975  	},
  1976  	{
  1977  		Name: "Cross Join",
  1978  		From: parser.FromClause{
  1979  			Tables: []parser.QueryExpression{
  1980  				parser.Table{
  1981  					Object: parser.Join{
  1982  						Table: parser.Table{
  1983  							Object: parser.Identifier{Literal: "table1"},
  1984  						},
  1985  						JoinTable: parser.Table{
  1986  							Object: parser.Identifier{Literal: "table2"},
  1987  						},
  1988  						JoinType: parser.Token{Token: parser.CROSS, Literal: "cross"},
  1989  					},
  1990  				},
  1991  			},
  1992  		},
  1993  		Result: &View{
  1994  			Header: []HeaderField{
  1995  				{View: "table1", Column: "column1", Number: 1, IsFromTable: true},
  1996  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  1997  				{View: "table2", Column: "column3", Number: 1, IsFromTable: true},
  1998  				{View: "table2", Column: "column4", Number: 2, IsFromTable: true},
  1999  			},
  2000  			RecordSet: []Record{
  2001  				NewRecord([]value.Primary{
  2002  					value.NewString("1"),
  2003  					value.NewString("str1"),
  2004  					value.NewString("2"),
  2005  					value.NewString("str22"),
  2006  				}),
  2007  				NewRecord([]value.Primary{
  2008  					value.NewString("1"),
  2009  					value.NewString("str1"),
  2010  					value.NewString("3"),
  2011  					value.NewString("str33"),
  2012  				}),
  2013  				NewRecord([]value.Primary{
  2014  					value.NewString("1"),
  2015  					value.NewString("str1"),
  2016  					value.NewString("4"),
  2017  					value.NewString("str44"),
  2018  				}),
  2019  				NewRecord([]value.Primary{
  2020  					value.NewString("2"),
  2021  					value.NewString("str2"),
  2022  					value.NewString("2"),
  2023  					value.NewString("str22"),
  2024  				}),
  2025  				NewRecord([]value.Primary{
  2026  					value.NewString("2"),
  2027  					value.NewString("str2"),
  2028  					value.NewString("3"),
  2029  					value.NewString("str33"),
  2030  				}),
  2031  				NewRecord([]value.Primary{
  2032  					value.NewString("2"),
  2033  					value.NewString("str2"),
  2034  					value.NewString("4"),
  2035  					value.NewString("str44"),
  2036  				}),
  2037  				NewRecord([]value.Primary{
  2038  					value.NewString("3"),
  2039  					value.NewString("str3"),
  2040  					value.NewString("2"),
  2041  					value.NewString("str22"),
  2042  				}),
  2043  				NewRecord([]value.Primary{
  2044  					value.NewString("3"),
  2045  					value.NewString("str3"),
  2046  					value.NewString("3"),
  2047  					value.NewString("str33"),
  2048  				}),
  2049  				NewRecord([]value.Primary{
  2050  					value.NewString("3"),
  2051  					value.NewString("str3"),
  2052  					value.NewString("4"),
  2053  					value.NewString("str44"),
  2054  				}),
  2055  			},
  2056  		},
  2057  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2058  			{scopeNameAliases: {
  2059  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
  2060  				"TABLE2": strings.ToUpper(GetTestFilePath("table2.csv")),
  2061  			}},
  2062  		}, time.Time{}, nil),
  2063  	},
  2064  	{
  2065  		Name: "Lateral Cross Join",
  2066  		From: parser.FromClause{
  2067  			Tables: []parser.QueryExpression{
  2068  				parser.Table{
  2069  					Object: parser.Join{
  2070  						Table: parser.Table{
  2071  							Object: parser.Identifier{Literal: "table1"},
  2072  						},
  2073  						JoinTable: parser.Table{
  2074  							Lateral: parser.Token{Token: parser.LATERAL},
  2075  							Object: parser.Subquery{
  2076  								Query: parser.SelectQuery{
  2077  									SelectEntity: parser.SelectEntity{
  2078  										SelectClause: parser.SelectClause{
  2079  											Fields: []parser.QueryExpression{
  2080  												parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column3"}}},
  2081  												parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column4"}}},
  2082  											},
  2083  										},
  2084  										FromClause: parser.FromClause{
  2085  											Tables: []parser.QueryExpression{
  2086  												parser.Table{Object: parser.Identifier{Literal: "table2"}},
  2087  											},
  2088  										},
  2089  										WhereClause: parser.WhereClause{
  2090  											Filter: parser.Comparison{
  2091  												LHS:      parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
  2092  												RHS:      parser.FieldReference{Column: parser.Identifier{Literal: "column3"}},
  2093  												Operator: parser.Token{Token: '=', Literal: "="},
  2094  											},
  2095  										},
  2096  									},
  2097  								},
  2098  							},
  2099  							Alias: parser.Identifier{
  2100  								Literal: "t2",
  2101  							},
  2102  						},
  2103  						JoinType: parser.Token{Token: parser.CROSS, Literal: "cross"},
  2104  					},
  2105  				},
  2106  			},
  2107  		},
  2108  		Result: &View{
  2109  			Header: []HeaderField{
  2110  				{View: "table1", Column: "column1", Number: 1, IsFromTable: true},
  2111  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  2112  				{View: "t2", Column: "column3", Number: 1, IsFromTable: true},
  2113  				{View: "t2", Column: "column4", Number: 2, IsFromTable: true},
  2114  			},
  2115  			RecordSet: []Record{
  2116  				NewRecord([]value.Primary{
  2117  					value.NewString("2"),
  2118  					value.NewString("str2"),
  2119  					value.NewString("2"),
  2120  					value.NewString("str22"),
  2121  				}),
  2122  				NewRecord([]value.Primary{
  2123  					value.NewString("3"),
  2124  					value.NewString("str3"),
  2125  					value.NewString("3"),
  2126  					value.NewString("str33"),
  2127  				}),
  2128  			},
  2129  		},
  2130  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2131  			{scopeNameAliases: {
  2132  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
  2133  			}},
  2134  		}, time.Time{}, nil),
  2135  	},
  2136  	{
  2137  		Name: "Inner Join",
  2138  		From: parser.FromClause{
  2139  			Tables: []parser.QueryExpression{
  2140  				parser.Table{
  2141  					Object: parser.Join{
  2142  						Table: parser.Table{
  2143  							Object: parser.Identifier{Literal: "table1"},
  2144  						},
  2145  						JoinTable: parser.Table{
  2146  							Object: parser.Identifier{Literal: "table2"},
  2147  						},
  2148  						Condition: parser.JoinCondition{
  2149  							On: parser.Comparison{
  2150  								LHS:      parser.FieldReference{View: parser.Identifier{Literal: "table1"}, Column: parser.Identifier{Literal: "column1"}},
  2151  								RHS:      parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column3"}},
  2152  								Operator: parser.Token{Token: '=', Literal: "="},
  2153  							},
  2154  						},
  2155  					},
  2156  				},
  2157  			},
  2158  		},
  2159  		Result: &View{
  2160  			Header: []HeaderField{
  2161  				{View: "table1", Column: "column1", Number: 1, IsFromTable: true},
  2162  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  2163  				{View: "table2", Column: "column3", Number: 1, IsFromTable: true},
  2164  				{View: "table2", Column: "column4", Number: 2, IsFromTable: true},
  2165  			},
  2166  			RecordSet: []Record{
  2167  				NewRecord([]value.Primary{
  2168  					value.NewString("2"),
  2169  					value.NewString("str2"),
  2170  					value.NewString("2"),
  2171  					value.NewString("str22"),
  2172  				}),
  2173  				NewRecord([]value.Primary{
  2174  					value.NewString("3"),
  2175  					value.NewString("str3"),
  2176  					value.NewString("3"),
  2177  					value.NewString("str33"),
  2178  				}),
  2179  			},
  2180  		},
  2181  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2182  			{scopeNameAliases: {
  2183  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
  2184  				"TABLE2": strings.ToUpper(GetTestFilePath("table2.csv")),
  2185  			}},
  2186  		}, time.Time{}, nil),
  2187  	},
  2188  	{
  2189  		Name: "Inner Join Using Condition",
  2190  		From: parser.FromClause{
  2191  			Tables: []parser.QueryExpression{
  2192  				parser.Table{
  2193  					Object: parser.Join{
  2194  						Table: parser.Table{
  2195  							Object: parser.Identifier{Literal: "table1"},
  2196  						},
  2197  						JoinTable: parser.Table{
  2198  							Object: parser.Identifier{Literal: "table1b"},
  2199  						},
  2200  						Condition: parser.JoinCondition{
  2201  							Using: []parser.QueryExpression{
  2202  								parser.Identifier{Literal: "column1"},
  2203  							},
  2204  						},
  2205  					},
  2206  				},
  2207  			},
  2208  		},
  2209  		Result: &View{
  2210  			Header: []HeaderField{
  2211  				{Column: "column1", IsFromTable: true, IsJoinColumn: true},
  2212  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  2213  				{View: "table1b", Column: "column2b", Number: 2, IsFromTable: true},
  2214  			},
  2215  			RecordSet: []Record{
  2216  				NewRecord([]value.Primary{
  2217  					value.NewString("2"),
  2218  					value.NewString("str2"),
  2219  					value.NewString("str2b"),
  2220  				}),
  2221  				NewRecord([]value.Primary{
  2222  					value.NewString("3"),
  2223  					value.NewString("str3"),
  2224  					value.NewString("str3b"),
  2225  				}),
  2226  			},
  2227  		},
  2228  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2229  			{scopeNameAliases: {
  2230  				"TABLE1":  strings.ToUpper(GetTestFilePath("table1.csv")),
  2231  				"TABLE1B": strings.ToUpper(GetTestFilePath("table1b.csv")),
  2232  			}},
  2233  		}, time.Time{}, nil),
  2234  	},
  2235  	{
  2236  		Name: "Outer Join",
  2237  		From: parser.FromClause{
  2238  			Tables: []parser.QueryExpression{
  2239  				parser.Table{
  2240  					Object: parser.Join{
  2241  						Table: parser.Table{
  2242  							Object: parser.Identifier{Literal: "table1"},
  2243  						},
  2244  						JoinTable: parser.Table{
  2245  							Object: parser.Identifier{Literal: "table2"},
  2246  						},
  2247  						Direction: parser.Token{Token: parser.LEFT, Literal: "left"},
  2248  						Condition: parser.JoinCondition{
  2249  							On: parser.Comparison{
  2250  								LHS:      parser.FieldReference{View: parser.Identifier{Literal: "table1"}, Column: parser.Identifier{Literal: "column1"}},
  2251  								RHS:      parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column3"}},
  2252  								Operator: parser.Token{Token: '=', Literal: "="},
  2253  							},
  2254  						},
  2255  					},
  2256  				},
  2257  			},
  2258  		},
  2259  		Result: &View{
  2260  			Header: []HeaderField{
  2261  				{View: "table1", Column: "column1", Number: 1, IsFromTable: true},
  2262  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  2263  				{View: "table2", Column: "column3", Number: 1, IsFromTable: true},
  2264  				{View: "table2", Column: "column4", Number: 2, IsFromTable: true},
  2265  			},
  2266  			RecordSet: []Record{
  2267  				NewRecord([]value.Primary{
  2268  					value.NewString("1"),
  2269  					value.NewString("str1"),
  2270  					value.NewNull(),
  2271  					value.NewNull(),
  2272  				}),
  2273  				NewRecord([]value.Primary{
  2274  					value.NewString("2"),
  2275  					value.NewString("str2"),
  2276  					value.NewString("2"),
  2277  					value.NewString("str22"),
  2278  				}),
  2279  				NewRecord([]value.Primary{
  2280  					value.NewString("3"),
  2281  					value.NewString("str3"),
  2282  					value.NewString("3"),
  2283  					value.NewString("str33"),
  2284  				}),
  2285  			},
  2286  		},
  2287  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2288  			{scopeNameAliases: {
  2289  				"TABLE1": strings.ToUpper(GetTestFilePath("table1.csv")),
  2290  				"TABLE2": strings.ToUpper(GetTestFilePath("table2.csv")),
  2291  			}},
  2292  		}, time.Time{}, nil),
  2293  	},
  2294  	{
  2295  		Name: "Outer Join Natural",
  2296  		From: parser.FromClause{
  2297  			Tables: []parser.QueryExpression{
  2298  				parser.Table{
  2299  					Object: parser.Join{
  2300  						Table: parser.Table{
  2301  							Object: parser.Identifier{Literal: "table1"},
  2302  						},
  2303  						JoinTable: parser.Table{
  2304  							Object: parser.Identifier{Literal: "table1b"},
  2305  						},
  2306  						Direction: parser.Token{Token: parser.RIGHT, Literal: "right"},
  2307  						Natural:   parser.Token{Token: parser.NATURAL, Literal: "natural"},
  2308  					},
  2309  				},
  2310  			},
  2311  		},
  2312  		Result: &View{
  2313  			Header: []HeaderField{
  2314  				{Column: "column1", IsFromTable: true, IsJoinColumn: true},
  2315  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  2316  				{View: "table1b", Column: "column2b", Number: 2, IsFromTable: true},
  2317  			},
  2318  			RecordSet: []Record{
  2319  				NewRecord([]value.Primary{
  2320  					value.NewString("2"),
  2321  					value.NewString("str2"),
  2322  					value.NewString("str2b"),
  2323  				}),
  2324  				NewRecord([]value.Primary{
  2325  					value.NewString("3"),
  2326  					value.NewString("str3"),
  2327  					value.NewString("str3b"),
  2328  				}),
  2329  				NewRecord([]value.Primary{
  2330  					value.NewString("4"),
  2331  					value.NewNull(),
  2332  					value.NewString("str4b"),
  2333  				}),
  2334  			},
  2335  		},
  2336  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2337  			{scopeNameAliases: {
  2338  				"TABLE1":  strings.ToUpper(GetTestFilePath("table1.csv")),
  2339  				"TABLE1B": strings.ToUpper(GetTestFilePath("table1b.csv")),
  2340  			}},
  2341  		}, time.Time{}, nil),
  2342  	},
  2343  	{
  2344  		Name: "Full Outer Join Natural",
  2345  		From: parser.FromClause{
  2346  			Tables: []parser.QueryExpression{
  2347  				parser.Table{
  2348  					Object: parser.Join{
  2349  						Table: parser.Table{
  2350  							Object: parser.Identifier{Literal: "table1"},
  2351  						},
  2352  						JoinTable: parser.Table{
  2353  							Object: parser.Identifier{Literal: "table1b"},
  2354  						},
  2355  						Direction: parser.Token{Token: parser.FULL, Literal: "full"},
  2356  						Natural:   parser.Token{Token: parser.NATURAL, Literal: "natural"},
  2357  					},
  2358  				},
  2359  			},
  2360  		},
  2361  		Result: &View{
  2362  			Header: []HeaderField{
  2363  				{Column: "column1", IsFromTable: true, IsJoinColumn: true},
  2364  				{View: "table1", Column: "column2", Number: 2, IsFromTable: true},
  2365  				{View: "table1b", Column: "column2b", Number: 2, IsFromTable: true},
  2366  			},
  2367  			RecordSet: []Record{
  2368  				NewRecord([]value.Primary{
  2369  					value.NewString("1"),
  2370  					value.NewString("str1"),
  2371  					value.NewNull(),
  2372  				}),
  2373  				NewRecord([]value.Primary{
  2374  					value.NewString("2"),
  2375  					value.NewString("str2"),
  2376  					value.NewString("str2b"),
  2377  				}),
  2378  				NewRecord([]value.Primary{
  2379  					value.NewString("3"),
  2380  					value.NewString("str3"),
  2381  					value.NewString("str3b"),
  2382  				}),
  2383  				NewRecord([]value.Primary{
  2384  					value.NewString("4"),
  2385  					value.NewNull(),
  2386  					value.NewString("str4b"),
  2387  				}),
  2388  			},
  2389  		},
  2390  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2391  			{scopeNameAliases: {
  2392  				"TABLE1":  strings.ToUpper(GetTestFilePath("table1.csv")),
  2393  				"TABLE1B": strings.ToUpper(GetTestFilePath("table1b.csv")),
  2394  			}},
  2395  		}, time.Time{}, nil),
  2396  	},
  2397  	{
  2398  		Name: "Incorrect LATERAL Usage Error",
  2399  		From: parser.FromClause{
  2400  			Tables: []parser.QueryExpression{
  2401  				parser.Table{
  2402  					Object: parser.Join{
  2403  						Table: parser.Table{
  2404  							Object: parser.Identifier{Literal: "table1"},
  2405  						},
  2406  						JoinTable: parser.Table{
  2407  							Lateral: parser.Token{Token: parser.LATERAL},
  2408  							Object: parser.Subquery{
  2409  								Query: parser.SelectQuery{
  2410  									SelectEntity: parser.SelectEntity{
  2411  										SelectClause: parser.SelectClause{
  2412  											Fields: []parser.QueryExpression{
  2413  												parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column3"}}},
  2414  												parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column4"}}},
  2415  											},
  2416  										},
  2417  										FromClause: parser.FromClause{
  2418  											Tables: []parser.QueryExpression{
  2419  												parser.Table{Object: parser.Identifier{Literal: "table2"}},
  2420  											},
  2421  										},
  2422  										WhereClause: parser.WhereClause{
  2423  											Filter: parser.Comparison{
  2424  												LHS:      parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
  2425  												RHS:      parser.FieldReference{Column: parser.Identifier{Literal: "column3"}},
  2426  												Operator: parser.Token{Token: '=', Literal: "="},
  2427  											},
  2428  										},
  2429  									},
  2430  								},
  2431  							},
  2432  						},
  2433  						Direction: parser.Token{Token: parser.FULL, Literal: "full"},
  2434  						Natural:   parser.Token{Token: parser.NATURAL, Literal: "natural"},
  2435  					},
  2436  				},
  2437  			},
  2438  		},
  2439  		Error: "LATERAL cannot to be used in a RIGHT or FULL outer join",
  2440  	},
  2441  	{
  2442  		Name: "Join Left Side Table File Not Exist Error",
  2443  		From: parser.FromClause{
  2444  			Tables: []parser.QueryExpression{
  2445  				parser.Table{
  2446  					Object: parser.Join{
  2447  						Table: parser.Table{
  2448  							Object: parser.Identifier{Literal: "notexist"},
  2449  						},
  2450  						JoinTable: parser.Table{
  2451  							Object: parser.Identifier{Literal: "table2"},
  2452  						},
  2453  						JoinType: parser.Token{Token: parser.CROSS, Literal: "cross"},
  2454  					},
  2455  				},
  2456  			},
  2457  		},
  2458  		Error: "file notexist does not exist",
  2459  	},
  2460  	{
  2461  		Name: "Join Right Side Table File Not Exist Error",
  2462  		From: parser.FromClause{
  2463  			Tables: []parser.QueryExpression{
  2464  				parser.Table{
  2465  					Object: parser.Join{
  2466  						Table: parser.Table{
  2467  							Object: parser.Identifier{Literal: "table1"},
  2468  						},
  2469  						JoinTable: parser.Table{
  2470  							Object: parser.Identifier{Literal: "notexist"},
  2471  						},
  2472  						JoinType: parser.Token{Token: parser.CROSS, Literal: "cross"},
  2473  					},
  2474  				},
  2475  			},
  2476  		},
  2477  		Error: "file notexist does not exist",
  2478  	},
  2479  	{
  2480  		Name: "LoadView from DATA table function",
  2481  		From: parser.FromClause{
  2482  			Tables: []parser.QueryExpression{
  2483  				parser.Table{
  2484  					Object: parser.TableFunction{
  2485  						Name: "data",
  2486  						Args: []parser.QueryExpression{
  2487  							parser.NewStringValue("c1,c2\n1,a\n2,b\n"),
  2488  						},
  2489  					},
  2490  					Alias: parser.Identifier{Literal: "ci"},
  2491  				},
  2492  			},
  2493  		},
  2494  		Result: &View{
  2495  			Header: NewHeader("ci", []string{"c1", "c2"}),
  2496  			RecordSet: []Record{
  2497  				NewRecord([]value.Primary{
  2498  					value.NewString("1"),
  2499  					value.NewString("a"),
  2500  				}),
  2501  				NewRecord([]value.Primary{
  2502  					value.NewString("2"),
  2503  					value.NewString("b"),
  2504  				}),
  2505  			},
  2506  			FileInfo: &FileInfo{
  2507  				Path:      "",
  2508  				Format:    option.CSV,
  2509  				Delimiter: ',',
  2510  				JsonQuery: "",
  2511  				Encoding:  text.UTF8,
  2512  				LineBreak: text.LF,
  2513  				ViewType:  ViewTypeStringObject,
  2514  			},
  2515  		},
  2516  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2517  			{
  2518  				scopeNameAliases: {
  2519  					"CI": "",
  2520  				},
  2521  			},
  2522  		}, time.Time{}, nil),
  2523  	},
  2524  	{ //TODO
  2525  		Name: "LoadView Inline Table as FormatSpecifiedFunction",
  2526  		From: parser.FromClause{
  2527  			Tables: []parser.QueryExpression{
  2528  				parser.Table{
  2529  					Object: parser.FormatSpecifiedFunction{
  2530  						Type:          parser.Token{Token: parser.CSV, Literal: "csv"},
  2531  						FormatElement: parser.NewStringValue(","),
  2532  						Path: parser.TableFunction{
  2533  							Name: "inline",
  2534  							Args: []parser.QueryExpression{
  2535  								parser.NewStringValue("table5"),
  2536  							},
  2537  						},
  2538  						Args: []parser.QueryExpression{
  2539  							parser.NewStringValue("SJIS"),
  2540  							parser.NewTernaryValueFromString("true"),
  2541  							parser.NewTernaryValueFromString("true"),
  2542  						},
  2543  					},
  2544  					Alias: parser.Identifier{Literal: "t"},
  2545  				},
  2546  			},
  2547  		},
  2548  		Result: &View{
  2549  			Header: NewHeader("t", []string{"c1", "c2"}),
  2550  			RecordSet: []Record{
  2551  				NewRecord([]value.Primary{
  2552  					value.NewString("1"),
  2553  					value.NewString("str1"),
  2554  				}),
  2555  				NewRecord([]value.Primary{
  2556  					value.NewString("2"),
  2557  					value.NewString(""),
  2558  				}),
  2559  				NewRecord([]value.Primary{
  2560  					value.NewString("3"),
  2561  					value.NewString("str3"),
  2562  				}),
  2563  			},
  2564  			FileInfo: &FileInfo{
  2565  				Path:      "",
  2566  				Delimiter: ',',
  2567  				Format:    option.CSV,
  2568  				Encoding:  text.SJIS,
  2569  				LineBreak: text.LF,
  2570  				NoHeader:  true,
  2571  				ViewType:  ViewTypeInlineTable,
  2572  			},
  2573  		},
  2574  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2575  			{scopeNameAliases: {
  2576  				"T": "",
  2577  			}},
  2578  		}, time.Time{}, nil),
  2579  	},
  2580  	{
  2581  		Name: "LoadView from Local File as URL",
  2582  		From: parser.FromClause{
  2583  			Tables: []parser.QueryExpression{
  2584  				parser.Table{
  2585  					Object: parser.Url{
  2586  						Raw: "file:./table.json",
  2587  					},
  2588  					Alias: parser.Identifier{Literal: "jt"},
  2589  				},
  2590  			},
  2591  		},
  2592  		Result: &View{
  2593  			Header: NewHeader("jt", []string{"item1", "item2"}),
  2594  			RecordSet: []Record{
  2595  				NewRecord([]value.Primary{
  2596  					value.NewString("value1"),
  2597  					value.NewFloat(1),
  2598  				}),
  2599  				NewRecord([]value.Primary{
  2600  					value.NewString("value2"),
  2601  					value.NewFloat(2),
  2602  				}),
  2603  			},
  2604  			FileInfo: &FileInfo{
  2605  				Path:      "table.json",
  2606  				Format:    option.JSON,
  2607  				Delimiter: ',',
  2608  				JsonQuery: "",
  2609  				Encoding:  text.UTF8,
  2610  				LineBreak: text.LF,
  2611  				ViewType:  ViewTypeFile,
  2612  			},
  2613  		},
  2614  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2615  			{
  2616  				scopeNameAliases: {
  2617  					"JT": strings.ToUpper(GetTestFilePath("table.json")),
  2618  				},
  2619  			},
  2620  		}, time.Time{}, nil),
  2621  	},
  2622  	{
  2623  		Name: "LoadView Json Inline Table",
  2624  		From: parser.FromClause{
  2625  			Tables: []parser.QueryExpression{
  2626  				parser.Table{
  2627  					Object: parser.FormatSpecifiedFunction{
  2628  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2629  						FormatElement: parser.NewStringValue("{column1, column2}"),
  2630  						Path:          parser.NewStringValue("[{\"column1\":1, \"column2\":2},{\"column1\":3, \"column2\":4}]"),
  2631  					},
  2632  					Alias: parser.Identifier{Literal: "jt"},
  2633  				},
  2634  			},
  2635  		},
  2636  		Result: &View{
  2637  			Header: NewHeader("jt", []string{"column1", "column2"}),
  2638  			RecordSet: []Record{
  2639  				NewRecord([]value.Primary{
  2640  					value.NewFloat(1),
  2641  					value.NewFloat(2),
  2642  				}),
  2643  				NewRecord([]value.Primary{
  2644  					value.NewFloat(3),
  2645  					value.NewFloat(4),
  2646  				}),
  2647  			},
  2648  			FileInfo: &FileInfo{
  2649  				Path:      "",
  2650  				Format:    option.JSON,
  2651  				Delimiter: ',',
  2652  				JsonQuery: "{column1, column2}",
  2653  				Encoding:  text.UTF8,
  2654  				LineBreak: text.LF,
  2655  				ViewType:  ViewTypeStringObject,
  2656  			},
  2657  		},
  2658  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2659  			{
  2660  				scopeNameAliases: {
  2661  					"JT": "",
  2662  				},
  2663  			},
  2664  		}, time.Time{}, nil),
  2665  	},
  2666  	{
  2667  		Name: "LoadView Json Inline Table Query Evaluation Error",
  2668  		From: parser.FromClause{
  2669  			Tables: []parser.QueryExpression{
  2670  				parser.Table{
  2671  					Object: parser.FormatSpecifiedFunction{
  2672  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2673  						FormatElement: parser.FieldReference{Column: parser.Identifier{Literal: "notexists"}},
  2674  						Path:          parser.NewStringValue("[{\"column1\":1, \"column2\":2},{\"column1\":3, \"column2\":4}]"),
  2675  					},
  2676  					Alias: parser.Identifier{Literal: "jt"},
  2677  				},
  2678  			},
  2679  		},
  2680  		Error: "field notexists does not exist",
  2681  	},
  2682  	{
  2683  		Name: "LoadView Json Inline Table JsonText Evaluation Error",
  2684  		From: parser.FromClause{
  2685  			Tables: []parser.QueryExpression{
  2686  				parser.Table{
  2687  					Object: parser.FormatSpecifiedFunction{
  2688  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2689  						FormatElement: parser.NewStringValue("{column1, column2}"),
  2690  						Path:          parser.FieldReference{Column: parser.Identifier{Literal: "notexists"}},
  2691  					},
  2692  					Alias: parser.Identifier{Literal: "jt"},
  2693  				},
  2694  			},
  2695  		},
  2696  		Error: "field notexists does not exist",
  2697  	},
  2698  	{
  2699  		Name: "LoadView Json Inline Table Query is Null",
  2700  		From: parser.FromClause{
  2701  			Tables: []parser.QueryExpression{
  2702  				parser.Table{
  2703  					Object: parser.FormatSpecifiedFunction{
  2704  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2705  						FormatElement: parser.NewNullValue(),
  2706  						Path:          parser.NewStringValue("[{\"column1\":1, \"column2\":2},{\"column1\":3, \"column2\":4}]"),
  2707  					},
  2708  					Alias: parser.Identifier{Literal: "jt"},
  2709  				},
  2710  			},
  2711  		},
  2712  		Error: "invalid json query: NULL",
  2713  	},
  2714  	{
  2715  		Name: "LoadView Json Inline Table JsonText is Null",
  2716  		From: parser.FromClause{
  2717  			Tables: []parser.QueryExpression{
  2718  				parser.Table{
  2719  					Object: parser.FormatSpecifiedFunction{
  2720  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2721  						FormatElement: parser.NewStringValue("{column1, column2}"),
  2722  						Path:          parser.NewNullValue(),
  2723  					},
  2724  					Alias: parser.Identifier{Literal: "jt"},
  2725  				},
  2726  			},
  2727  		},
  2728  		Error: "inline table is empty",
  2729  	},
  2730  	{
  2731  		Name: "LoadView Json Inline Table Loading Error",
  2732  		From: parser.FromClause{
  2733  			Tables: []parser.QueryExpression{
  2734  				parser.Table{
  2735  					Object: parser.FormatSpecifiedFunction{
  2736  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2737  						FormatElement: parser.NewStringValue("{column1, column2"),
  2738  						Path:          parser.NewStringValue("[{\"column1\":1, \"column2\":2},{\"column1\":3, \"column2\":4}]"),
  2739  					},
  2740  					Alias: parser.Identifier{Literal: "jt"},
  2741  				},
  2742  			},
  2743  		},
  2744  		Error: "json loading error: column 17: unexpected termination",
  2745  	},
  2746  	{
  2747  		Name: "LoadView Json Inline Table From File",
  2748  		From: parser.FromClause{
  2749  			Tables: []parser.QueryExpression{
  2750  				parser.Table{
  2751  					Object: parser.FormatSpecifiedFunction{
  2752  						Type:          parser.Token{Token: parser.JSON_INLINE, Literal: "json_inline"},
  2753  						FormatElement: parser.NewStringValue("{}"),
  2754  						Path:          parser.Identifier{Literal: "table"},
  2755  					},
  2756  					Alias: parser.Identifier{Literal: "jt"},
  2757  				},
  2758  			},
  2759  		},
  2760  		Result: &View{
  2761  			Header: NewHeader("jt", []string{"item1", "item2"}),
  2762  			RecordSet: []Record{
  2763  				NewRecord([]value.Primary{
  2764  					value.NewString("value1"),
  2765  					value.NewFloat(1),
  2766  				}),
  2767  				NewRecord([]value.Primary{
  2768  					value.NewString("value2"),
  2769  					value.NewFloat(2),
  2770  				}),
  2771  			},
  2772  			FileInfo: &FileInfo{
  2773  				Path:      "",
  2774  				Format:    option.JSON,
  2775  				Delimiter: ',',
  2776  				JsonQuery: "{}",
  2777  				Encoding:  text.UTF8,
  2778  				LineBreak: text.LF,
  2779  				ViewType:  ViewTypeInlineTable,
  2780  			},
  2781  		},
  2782  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2783  			{
  2784  				scopeNameAliases: {
  2785  					"JT": "",
  2786  				},
  2787  			},
  2788  		}, time.Time{}, nil),
  2789  	},
  2790  	{
  2791  		Name: "LoadView Json Inline Table From File with No Alias",
  2792  		From: parser.FromClause{
  2793  			Tables: []parser.QueryExpression{
  2794  				parser.Table{
  2795  					Object: parser.FormatSpecifiedFunction{
  2796  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2797  						FormatElement: parser.NewStringValue("{}"),
  2798  						Path:          parser.Identifier{Literal: "table"},
  2799  					},
  2800  				},
  2801  			},
  2802  		},
  2803  		Result: &View{
  2804  			Header: NewHeader("table", []string{"item1", "item2"}),
  2805  			RecordSet: []Record{
  2806  				NewRecord([]value.Primary{
  2807  					value.NewString("value1"),
  2808  					value.NewFloat(1),
  2809  				}),
  2810  				NewRecord([]value.Primary{
  2811  					value.NewString("value2"),
  2812  					value.NewFloat(2),
  2813  				}),
  2814  			},
  2815  			FileInfo: &FileInfo{
  2816  				Path:      "",
  2817  				Format:    option.JSON,
  2818  				Delimiter: ',',
  2819  				JsonQuery: "{}",
  2820  				Encoding:  text.UTF8,
  2821  				LineBreak: text.LF,
  2822  				ViewType:  ViewTypeInlineTable,
  2823  			},
  2824  		},
  2825  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2826  			{
  2827  				scopeNameAliases: {
  2828  					"TABLE": "",
  2829  				},
  2830  			},
  2831  		}, time.Time{}, nil),
  2832  	},
  2833  	{
  2834  		Name: "LoadView Json Inline Table From File Path Error",
  2835  		From: parser.FromClause{
  2836  			Tables: []parser.QueryExpression{
  2837  				parser.Table{
  2838  					Object: parser.FormatSpecifiedFunction{
  2839  						Type:          parser.Token{Token: parser.JSON_TABLE, Literal: "json_table"},
  2840  						FormatElement: parser.NewStringValue("{}"),
  2841  						Path:          parser.Identifier{Literal: "notexist"},
  2842  					},
  2843  					Alias: parser.Identifier{Literal: "jt"},
  2844  				},
  2845  			},
  2846  		},
  2847  		Error: "file notexist does not exist",
  2848  	},
  2849  	{
  2850  		Name: "LoadView CSV Inline Table",
  2851  		From: parser.FromClause{
  2852  			Tables: []parser.QueryExpression{
  2853  				parser.Table{
  2854  					Object: parser.FormatSpecifiedFunction{
  2855  						Type:          parser.Token{Token: parser.CSV_INLINE, Literal: "csv_inline"},
  2856  						FormatElement: parser.NewStringValue(","),
  2857  						Path:          parser.NewStringValue("c1,c2\n1,a\n2,b\n"),
  2858  					},
  2859  					Alias: parser.Identifier{Literal: "ci"},
  2860  				},
  2861  			},
  2862  		},
  2863  		Result: &View{
  2864  			Header: NewHeader("ci", []string{"c1", "c2"}),
  2865  			RecordSet: []Record{
  2866  				NewRecord([]value.Primary{
  2867  					value.NewString("1"),
  2868  					value.NewString("a"),
  2869  				}),
  2870  				NewRecord([]value.Primary{
  2871  					value.NewString("2"),
  2872  					value.NewString("b"),
  2873  				}),
  2874  			},
  2875  			FileInfo: &FileInfo{
  2876  				Path:      "",
  2877  				Format:    option.CSV,
  2878  				Delimiter: ',',
  2879  				JsonQuery: "",
  2880  				Encoding:  text.UTF8,
  2881  				LineBreak: text.LF,
  2882  				ViewType:  ViewTypeStringObject,
  2883  			},
  2884  		},
  2885  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2886  			{
  2887  				scopeNameAliases: {
  2888  					"CI": "",
  2889  				},
  2890  			},
  2891  		}, time.Time{}, nil),
  2892  	},
  2893  	{
  2894  		Name: "LoadView Subquery",
  2895  		From: parser.FromClause{
  2896  			Tables: []parser.QueryExpression{
  2897  				parser.Table{
  2898  					Object: parser.Subquery{
  2899  						Query: parser.SelectQuery{
  2900  							SelectEntity: parser.SelectEntity{
  2901  								SelectClause: parser.SelectClause{
  2902  									Fields: []parser.QueryExpression{
  2903  										parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
  2904  										parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
  2905  									},
  2906  								},
  2907  								FromClause: parser.FromClause{
  2908  									Tables: []parser.QueryExpression{
  2909  										parser.Table{Object: parser.Identifier{Literal: "table1"}},
  2910  									},
  2911  								},
  2912  							},
  2913  						},
  2914  					},
  2915  				},
  2916  			},
  2917  		},
  2918  		Result: &View{
  2919  			Header: NewHeader("table1", []string{"column1", "column2"}),
  2920  			RecordSet: []Record{
  2921  				NewRecord([]value.Primary{
  2922  					value.NewString("1"),
  2923  					value.NewString("str1"),
  2924  				}),
  2925  				NewRecord([]value.Primary{
  2926  					value.NewString("2"),
  2927  					value.NewString("str2"),
  2928  				}),
  2929  				NewRecord([]value.Primary{
  2930  					value.NewString("3"),
  2931  					value.NewString("str3"),
  2932  				}),
  2933  			},
  2934  		},
  2935  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{{}}, time.Time{}, nil),
  2936  	},
  2937  	{
  2938  		Name: "LoadView Subquery with Table Name Alias",
  2939  		From: parser.FromClause{
  2940  			Tables: []parser.QueryExpression{
  2941  				parser.Table{
  2942  					Object: parser.Subquery{
  2943  						Query: parser.SelectQuery{
  2944  							SelectEntity: parser.SelectEntity{
  2945  								SelectClause: parser.SelectClause{
  2946  									Fields: []parser.QueryExpression{
  2947  										parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
  2948  										parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
  2949  									},
  2950  								},
  2951  								FromClause: parser.FromClause{
  2952  									Tables: []parser.QueryExpression{
  2953  										parser.Table{Object: parser.Identifier{Literal: "table1"}},
  2954  									},
  2955  								},
  2956  							},
  2957  						},
  2958  					},
  2959  					Alias: parser.Identifier{Literal: "alias"},
  2960  				},
  2961  			},
  2962  		},
  2963  		Result: &View{
  2964  			Header: NewHeader("alias", []string{"column1", "column2"}),
  2965  			RecordSet: []Record{
  2966  				NewRecord([]value.Primary{
  2967  					value.NewString("1"),
  2968  					value.NewString("str1"),
  2969  				}),
  2970  				NewRecord([]value.Primary{
  2971  					value.NewString("2"),
  2972  					value.NewString("str2"),
  2973  				}),
  2974  				NewRecord([]value.Primary{
  2975  					value.NewString("3"),
  2976  					value.NewString("str3"),
  2977  				}),
  2978  			},
  2979  		},
  2980  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  2981  			{
  2982  				scopeNameAliases: {
  2983  					"ALIAS": "",
  2984  				},
  2985  			},
  2986  		}, time.Time{}, nil),
  2987  	},
  2988  	{
  2989  		Name: "LoadView Subquery Duplicate Table Name Error",
  2990  		From: parser.FromClause{
  2991  			Tables: []parser.QueryExpression{
  2992  				parser.Table{Object: parser.Identifier{Literal: "table1"}, Alias: parser.Identifier{Literal: "t"}},
  2993  				parser.Table{
  2994  					Object: parser.Subquery{
  2995  						Query: parser.SelectQuery{
  2996  							SelectEntity: parser.SelectEntity{
  2997  								SelectClause: parser.SelectClause{
  2998  									Fields: []parser.QueryExpression{
  2999  										parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
  3000  										parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
  3001  									},
  3002  								},
  3003  								FromClause: parser.FromClause{
  3004  									Tables: []parser.QueryExpression{
  3005  										parser.Table{Object: parser.Identifier{Literal: "table1"}},
  3006  									},
  3007  								},
  3008  							},
  3009  						},
  3010  					},
  3011  					Alias: parser.Identifier{Literal: "t"},
  3012  				},
  3013  			},
  3014  		},
  3015  		Error: "table name t is a duplicate",
  3016  	},
  3017  	{
  3018  		Name: "LoadView CSV Parse Error",
  3019  		From: parser.FromClause{
  3020  			Tables: []parser.QueryExpression{
  3021  				parser.Table{
  3022  					Object: parser.Identifier{Literal: "table_broken.csv"},
  3023  				},
  3024  			},
  3025  		},
  3026  		Error: fmt.Sprintf("data parse error in %s: line 3, column 7: wrong number of fields in line", GetTestFilePath("table_broken.csv")),
  3027  	},
  3028  	{
  3029  		Name: "Allow Uneven Field Length",
  3030  		From: parser.FromClause{
  3031  			Tables: []parser.QueryExpression{
  3032  				parser.Table{
  3033  					Object: parser.Identifier{Literal: "table_broken.csv"},
  3034  				},
  3035  			},
  3036  		},
  3037  		AllowUnevenFields: true,
  3038  		Result: &View{
  3039  			Header: NewHeader("table_broken", []string{"column1", "column2", "__@3__"}),
  3040  			RecordSet: []Record{
  3041  				NewRecord([]value.Primary{
  3042  					value.NewString("1"),
  3043  					value.NewString("str1"),
  3044  					value.NewNull(),
  3045  				}),
  3046  				NewRecord([]value.Primary{
  3047  					value.NewString("2"),
  3048  					value.NewString("str2"),
  3049  					value.NewString("str2"),
  3050  				}),
  3051  				NewRecord([]value.Primary{
  3052  					value.NewString("3"),
  3053  					value.NewString("str3"),
  3054  					value.NewNull(),
  3055  				}),
  3056  			},
  3057  			FileInfo: &FileInfo{
  3058  				Path:      "table_broken.csv",
  3059  				Delimiter: ',',
  3060  				Encoding:  text.UTF8,
  3061  				LineBreak: text.LF,
  3062  			},
  3063  		},
  3064  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  3065  			{scopeNameAliases: {
  3066  				"TABLE_BROKEN": strings.ToUpper(GetTestFilePath("table_broken.csv")),
  3067  			}},
  3068  		}, time.Time{}, nil),
  3069  	},
  3070  	{
  3071  		Name: "Allow Uneven Field Length without Null",
  3072  		From: parser.FromClause{
  3073  			Tables: []parser.QueryExpression{
  3074  				parser.Table{
  3075  					Object: parser.Identifier{Literal: "table_broken.csv"},
  3076  				},
  3077  			},
  3078  		},
  3079  		AllowUnevenFields: true,
  3080  		WithoutNull:       true,
  3081  		Result: &View{
  3082  			Header: NewHeader("table_broken", []string{"column1", "column2", "__@3__"}),
  3083  			RecordSet: []Record{
  3084  				NewRecord([]value.Primary{
  3085  					value.NewString("1"),
  3086  					value.NewString("str1"),
  3087  					value.NewString(""),
  3088  				}),
  3089  				NewRecord([]value.Primary{
  3090  					value.NewString("2"),
  3091  					value.NewString("str2"),
  3092  					value.NewString("str2"),
  3093  				}),
  3094  				NewRecord([]value.Primary{
  3095  					value.NewString("3"),
  3096  					value.NewString("str3"),
  3097  					value.NewString(""),
  3098  				}),
  3099  			},
  3100  			FileInfo: &FileInfo{
  3101  				Path:      "table_broken.csv",
  3102  				Delimiter: ',',
  3103  				Encoding:  text.UTF8,
  3104  				LineBreak: text.LF,
  3105  			},
  3106  		},
  3107  		ResultScope: GenerateReferenceScope(nil, []map[string]map[string]interface{}{
  3108  			{scopeNameAliases: {
  3109  				"TABLE_BROKEN": strings.ToUpper(GetTestFilePath("table_broken.csv")),
  3110  			}},
  3111  		}, time.Time{}, nil),
  3112  	},
  3113  	{
  3114  		Name: "Inner Join Join Error",
  3115  		From: parser.FromClause{
  3116  			Tables: []parser.QueryExpression{
  3117  				parser.Table{
  3118  					Object: parser.Join{
  3119  						Table: parser.Table{
  3120  							Object: parser.Identifier{Literal: "table1"},
  3121  						},
  3122  						JoinTable: parser.Table{
  3123  							Object: parser.Identifier{Literal: "table2"},
  3124  						},
  3125  						Condition: parser.JoinCondition{
  3126  							On: parser.Comparison{
  3127  								LHS:      parser.FieldReference{View: parser.Identifier{Literal: "table1"}, Column: parser.Identifier{Literal: "notexist"}},
  3128  								RHS:      parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "column3"}},
  3129  								Operator: parser.Token{Token: '=', Literal: "="},
  3130  							},
  3131  						},
  3132  					},
  3133  				},
  3134  			},
  3135  		},
  3136  		Error: "field table1.notexist does not exist",
  3137  	},
  3138  	{
  3139  		Name: "Outer Join Join Error",
  3140  		From: parser.FromClause{
  3141  			Tables: []parser.QueryExpression{
  3142  				parser.Table{
  3143  					Object: parser.Join{
  3144  						Table: parser.Table{
  3145  							Object: parser.Identifier{Literal: "table1"},
  3146  						},
  3147  						JoinTable: parser.Table{
  3148  							Object: parser.Identifier{Literal: "table2"},
  3149  						},
  3150  						Direction: parser.Token{Token: parser.LEFT, Literal: "left"},
  3151  						Condition: parser.JoinCondition{
  3152  							On: parser.Comparison{
  3153  								LHS:      parser.FieldReference{View: parser.Identifier{Literal: "table1"}, Column: parser.Identifier{Literal: "column1"}},
  3154  								RHS:      parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "notexist"}},
  3155  								Operator: parser.Token{Token: '=', Literal: "="},
  3156  							},
  3157  						},
  3158  					},
  3159  				},
  3160  			},
  3161  		},
  3162  		Error: "field table2.notexist does not exist",
  3163  	},
  3164  	{
  3165  		Name: "Inner Join Using Condition Error",
  3166  		From: parser.FromClause{
  3167  			Tables: []parser.QueryExpression{
  3168  				parser.Table{
  3169  					Object: parser.Join{
  3170  						Table: parser.Table{
  3171  							Object: parser.Identifier{Literal: "table1"},
  3172  						},
  3173  						JoinTable: parser.Table{
  3174  							Object: parser.Identifier{Literal: "table1b"},
  3175  						},
  3176  						Condition: parser.JoinCondition{
  3177  							Using: []parser.QueryExpression{
  3178  								parser.Identifier{Literal: "notexist"},
  3179  							},
  3180  						},
  3181  					},
  3182  				},
  3183  			},
  3184  		},
  3185  		Error: "field notexist does not exist",
  3186  	},
  3187  }
  3188  
  3189  func TestLoadView(t *testing.T) {
  3190  	defer func() {
  3191  		_ = TestTx.ReleaseResources()
  3192  		_ = TestTx.CachedViews.Clean(TestTx.FileContainer)
  3193  		_ = TestTx.Session.SetStdin(os.Stdin)
  3194  		initFlag(TestTx.Flags)
  3195  	}()
  3196  
  3197  	TestTx.Flags.Repository = TestDir
  3198  	ctx := context.Background()
  3199  
  3200  	for _, v := range loadViewTests {
  3201  		TestTx.UnlockStdin()
  3202  		_ = TestTx.CachedViews.Clean(TestTx.FileContainer)
  3203  
  3204  		_ = TestTx.Session.SetStdin(os.Stdin)
  3205  		TestTx.Flags.ImportOptions.Format = v.ImportFormat
  3206  		TestTx.Flags.ImportOptions.Delimiter = ','
  3207  		if v.Delimiter != 0 {
  3208  			TestTx.Flags.ImportOptions.Delimiter = v.Delimiter
  3209  		}
  3210  		TestTx.Flags.ImportOptions.AllowUnevenFields = v.AllowUnevenFields
  3211  		TestTx.Flags.ImportOptions.DelimiterPositions = v.DelimiterPositions
  3212  		TestTx.Flags.ImportOptions.SingleLine = v.SingleLine
  3213  		TestTx.Flags.ImportOptions.JsonQuery = v.JsonQuery
  3214  		TestTx.Flags.ImportOptions.NoHeader = v.NoHeader
  3215  		TestTx.Flags.ImportOptions.WithoutNull = v.WithoutNull
  3216  		if v.Encoding != text.AUTO {
  3217  			TestTx.Flags.ImportOptions.Encoding = v.Encoding
  3218  		} else {
  3219  			TestTx.Flags.ImportOptions.Encoding = text.UTF8
  3220  		}
  3221  
  3222  		if 0 < len(v.Stdin) {
  3223  			_ = TestTx.Session.SetStdin(NewInput(strings.NewReader(v.Stdin)))
  3224  		} else {
  3225  			_ = TestTx.Session.SetStdin(nil)
  3226  		}
  3227  
  3228  		if v.Scope == nil {
  3229  			v.Scope = NewReferenceScope(TestTx)
  3230  		}
  3231  
  3232  		queryScope := v.Scope.CreateNode()
  3233  		view, err := LoadView(ctx, queryScope, v.From.Tables, v.ForUpdate, v.UseInternalId)
  3234  		if v.TestCache {
  3235  			queryScope.nodes[len(queryScope.nodes)-1].Clear()
  3236  			view, err = LoadView(ctx, queryScope, v.From.Tables, v.ForUpdate, v.UseInternalId)
  3237  		}
  3238  
  3239  		if err != nil {
  3240  			if len(v.Error) < 1 {
  3241  				t.Errorf("%s: unexpected error %q", v.Name, err)
  3242  			} else if err.Error() != v.Error {
  3243  				t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
  3244  			}
  3245  			continue
  3246  		}
  3247  		if 0 < len(v.Error) {
  3248  			t.Errorf("%s: no error, want error %q", v.Name, v.Error)
  3249  			continue
  3250  		}
  3251  
  3252  		if v.Result.FileInfo != nil {
  3253  			if filepath.Base(view.FileInfo.Path) != filepath.Base(v.Result.FileInfo.Path) {
  3254  				t.Errorf("%s: FileInfo.Path = %q, want %q", v.Name, filepath.Base(view.FileInfo.Path), filepath.Base(v.Result.FileInfo.Path))
  3255  			}
  3256  			if view.FileInfo.Format != v.Result.FileInfo.Format {
  3257  				t.Errorf("%s: FileInfo.Format = %s, want %s", v.Name, view.FileInfo.Format, v.Result.FileInfo.Format)
  3258  			}
  3259  			if view.FileInfo.Delimiter != v.Result.FileInfo.Delimiter {
  3260  				t.Errorf("%s: FileInfo.Delimiter = %q, want %q", v.Name, view.FileInfo.Delimiter, v.Result.FileInfo.Delimiter)
  3261  			}
  3262  			if !reflect.DeepEqual(view.FileInfo.DelimiterPositions, v.Result.FileInfo.DelimiterPositions) {
  3263  				t.Errorf("%s: FileInfo.DelimiterPositions = %v, want %v", v.Name, view.FileInfo.DelimiterPositions, v.Result.FileInfo.DelimiterPositions)
  3264  			}
  3265  			if view.FileInfo.JsonQuery != v.Result.FileInfo.JsonQuery {
  3266  				t.Errorf("%s: FileInfo.JsonQuery = %q, want %q", v.Name, view.FileInfo.JsonQuery, v.Result.FileInfo.JsonQuery)
  3267  			}
  3268  			if view.FileInfo.Encoding != v.Result.FileInfo.Encoding {
  3269  				t.Errorf("%s: FileInfo.Encoding = %s, want %s", v.Name, view.FileInfo.Encoding, v.Result.FileInfo.Encoding)
  3270  			}
  3271  			if view.FileInfo.LineBreak != v.Result.FileInfo.LineBreak {
  3272  				t.Errorf("%s: FileInfo.LineBreak = %s, want %s", v.Name, view.FileInfo.LineBreak, v.Result.FileInfo.LineBreak)
  3273  			}
  3274  			if view.FileInfo.NoHeader != v.Result.FileInfo.NoHeader {
  3275  				t.Errorf("%s: FileInfo.NoHeader = %t, want %t", v.Name, view.FileInfo.NoHeader, v.Result.FileInfo.NoHeader)
  3276  			}
  3277  			if view.FileInfo.PrettyPrint != v.Result.FileInfo.PrettyPrint {
  3278  				t.Errorf("%s: FileInfo.PrettyPrint = %t, want %t", v.Name, view.FileInfo.PrettyPrint, v.Result.FileInfo.PrettyPrint)
  3279  			}
  3280  			if view.FileInfo.ForUpdate != v.Result.FileInfo.ForUpdate {
  3281  				t.Errorf("%s: FileInfo.ForUpdate = %t, want %t", v.Name, view.FileInfo.ForUpdate, v.Result.FileInfo.ForUpdate)
  3282  			}
  3283  			if view.FileInfo.ViewType != v.Result.FileInfo.ViewType {
  3284  				t.Errorf("%s: FileInfo.ViewType = %d, want %d", v.Name, view.FileInfo.ViewType, v.Result.FileInfo.ViewType)
  3285  			}
  3286  		}
  3287  		if view.FileInfo != nil {
  3288  			_ = TestTx.FileContainer.Close(view.FileInfo.Handler)
  3289  			view.FileInfo = nil
  3290  		}
  3291  		v.Result.FileInfo = nil
  3292  
  3293  		if v.ResultScope == nil {
  3294  			v.ResultScope = NewReferenceScope(TestTx).CreateNode()
  3295  		}
  3296  
  3297  		if !NodeScopeListEqual(queryScope.nodes, v.ResultScope.nodes) {
  3298  			t.Errorf("%s: node list = %v, want %v", v.Name, queryScope.nodes, v.ResultScope.nodes)
  3299  		}
  3300  		for i := range queryScope.Blocks {
  3301  			if !reflect.DeepEqual(queryScope.Blocks[i].TemporaryTables.Keys(), v.ResultScope.Blocks[i].TemporaryTables.Keys()) {
  3302  				t.Errorf("%s: temp view list = %v, want %v", v.Name, queryScope.Blocks[i].TemporaryTables.Keys(), v.ResultScope.Blocks[i].TemporaryTables.Keys())
  3303  			}
  3304  		}
  3305  
  3306  		if !reflect.DeepEqual(view, v.Result) {
  3307  			t.Errorf("%s: \n result = %v,\n expect = %v", v.Name, view, v.Result)
  3308  		}
  3309  	}
  3310  }