Commit e3774e7a authored by cznic's avatar cznic

WIP, updates #85.

parent 6c3c2c28
......@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//MAYBE set operations
//MAYBE IN ( SELECT ... )
//MAYBE +=, -=, ...
//TODO verify there's a graceful failure for a 2G+ blob on a 32 bit machine.
......@@ -826,7 +825,7 @@
// Predicate = (
// [ "NOT" ] (
// "IN" "(" ExpressionList ")"
// | "IN" "(" SelectStmt ")"
// | "IN" "(" SelectStmt [ ";" ] ")"
// | "BETWEEN" PrimaryFactor "AND" PrimaryFactor
// )
// | "IS" [ "NOT" ] "NULL"
......@@ -1421,11 +1420,21 @@
// BEGIN TRANSACTION;
// CREATE TABLE department (
// DepartmentID int,
// DepartmentName string DepartmentName IN ("HQ", "R/D", "Lab", "HR")
// DEFAULT "HQ",
// DepartmentName string DepartmentName IN ("HQ", "R/D", "Lab", "HR") DEFAULT "HQ",
// );
// COMMIT;
//
// Note that the constraint and/or default expressions may refer to other
// columns by name:
//
// BEGIN TRANSACTION;
// CREATE TABLE t (
// a int,
// b int b > a && b < c DEFAULT (a+c)/2,
// c int,
// );
// COMMIT;
//
//
// Constraints and defaults evaluation order
//
......
......@@ -3037,12 +3037,25 @@ func (l value) String() string {
switch x := l.val.(type) {
case nil:
return "NULL"
case idealComplex:
s := fmt.Sprint(x)
return s[1 : len(s)-1]
case complex64:
s := fmt.Sprint(x)
return s[1 : len(s)-1]
case complex128:
s := fmt.Sprint(x)
return s[1 : len(s)-1]
case string:
return fmt.Sprintf("%q", x)
case time.Duration:
return fmt.Sprintf("duration(%q)", l.val)
case time.Time:
return fmt.Sprintf("time(%q)", l.val)
case *big.Rat:
return fmt.Sprintf("bigrat(%q)", l.val)
case *big.Int:
return fmt.Sprintf(`bigint("%v")`, l.val)
default:
return fmt.Sprintf("%v", l.val)
}
......
This diff is collapsed.
......@@ -455,11 +455,11 @@ Factor:
{
$$ = &pIn{expr: $1.(expression), not: true, list: $5.([]expression)}
}
| Factor1 in '(' SelectStmt ')'
| Factor1 in '(' SelectStmt semiOpt ')'
{
$$ = &pIn{expr: $1.(expression), sel: $4.(*selectStmt)}
}
| Factor1 not in '(' SelectStmt ')'
| Factor1 not in '(' SelectStmt semiOpt ')'
{
$$ = &pIn{expr: $1.(expression), not: true, sel: $5.(*selectStmt)}
}
......@@ -850,12 +850,12 @@ RecordSet:
RecordSet1:
identifier
| '(' SelectStmt RecordSet11 ')'
| '(' SelectStmt semiOpt ')'
{
$$ = $2
}
RecordSet11:
semiOpt:
/* EMPTY */
| ';'
......
......@@ -126,7 +126,7 @@ OrderBy = "ORDER" "BY" ExpressionList [ "ASC" | "DESC" ] .
Predicate = (
[ "NOT" ] (
"IN" "(" ExpressionList ")"
| "IN" "(" SelectStmt ")"
| "IN" "(" SelectStmt [ ";" ] ")"
| "BETWEEN" PrimaryFactor "AND" PrimaryFactor
)
| "IS" [ "NOT" ] "NULL"
......
This diff is collapsed.
......@@ -83,7 +83,7 @@ func str2expr(expr string) (expression, error) {
}
func (s *updateStmt) String() string {
u := fmt.Sprintf("UPDATE TABLE %s", s.tableName)
u := fmt.Sprintf("UPDATE %s", s.tableName)
a := make([]string, len(s.list))
for i, v := range s.list {
a[i] = v.String()
......@@ -92,7 +92,7 @@ func (s *updateStmt) String() string {
if s.where != nil {
w = fmt.Sprintf(" WHERE %s", s.where)
}
return fmt.Sprintf("%s %s%s", u, strings.Join(a, ", "), w)
return fmt.Sprintf("%s %s%s;", u, strings.Join(a, ", "), w)
}
func (s *updateStmt) exec(ctx *execCtx) (_ Recordset, err error) {
......@@ -454,7 +454,7 @@ type alterTableAddStmt struct {
}
func (s *alterTableAddStmt) String() string {
r := fmt.Sprintf("ALTER TABLE %s ADD %s %s;", s.tableName, s.c.name, typeStr(s.c.typ))
r := fmt.Sprintf("ALTER TABLE %s ADD %s %s", s.tableName, s.c.name, typeStr(s.c.typ))
c := s.c
if x := c.constraint; x != nil { //TODO add (*col).String()
switch e := x.expr; {
......@@ -467,7 +467,7 @@ func (s *alterTableAddStmt) String() string {
if x := c.dflt; x != nil {
r += " DEFAULT " + x.String()
}
return r
return r + ";"
}
func (s *alterTableAddStmt) exec(ctx *execCtx) (Recordset, error) {
......@@ -550,7 +550,7 @@ func (s *selectStmt) String() string {
a := make([]string, len(s.flds))
for i, v := range s.flds {
s := v.expr.String()
if v.name != "" {
if v.name != "" && v.name != s {
s += " AS " + v.name
}
a[i] = s
......@@ -689,7 +689,7 @@ func (s *insertIntoStmt) String() string {
}
switch {
case s.sel != nil:
return fmt.Sprintf("INSERT INTO %s%s (%s);", s.tableName, cn, s.sel)
return fmt.Sprintf("INSERT INTO %s%s %s;", s.tableName, cn, s.sel)
default:
a := make([]string, len(s.lists))
for i, v := range s.lists {
......
......@@ -267,6 +267,27 @@ func test(t *testing.T, s testDB) (panicked error) {
continue
}
s1 := list.String()
list1, err := Compile(s1)
if err != nil {
t.Errorf("recreated source does not compile: %v\n---- orig\n%s\n---- recreated\n%s", err, q, s1)
if *oFastFail {
return
}
continue
}
s2 := list1.String()
if g, e := s2, s1; g != e {
t.Errorf("recreated source is not idempotent\n---- orig\n%s\n---- recreated1\n%s\n---- recreated2\n%s", q, s1, s2)
if *oFastFail {
return
}
continue
}
tctx := NewRWCtx()
if !func() (ok bool) {
defer func() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment