Derive a column's datatype in columnDatatype alone
This commit is contained in:
+17
-30
@@ -82,8 +82,14 @@ func checkColumns(s nodeScope) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := columnDatatype(column); err != nil {
|
||||
return fmt.Errorf("%s: field %q: %w", path, name, err)
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
first := itemDatatype(items[0])
|
||||
for _, it := range items[1:] {
|
||||
if d := itemDatatype(it); d != first {
|
||||
return fmt.Errorf("%s: field %q: %w", path, name, disagreement(items[0], first, it, d))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -101,41 +107,22 @@ func checkColumns(s nodeScope) error {
|
||||
})
|
||||
}
|
||||
|
||||
// columnDatatype is the datatype a column's items hold. They must agree, since a
|
||||
// column holds one; a column only ever null is a string.
|
||||
func columnDatatype(n node) (DataType, error) {
|
||||
// columnDatatype is the datatype a column holds, which its first item decides: checkColumns refuses
|
||||
// a column whose items disagree. A table's column, like one only ever null, has no item and is a string.
|
||||
func columnDatatype(n node) DataType {
|
||||
items, _ := columnItems(n)
|
||||
if len(items) == 0 {
|
||||
return DataTypeString, nil
|
||||
return DataTypeString
|
||||
}
|
||||
first := itemDatatype(items[0])
|
||||
for _, t := range items[1:] {
|
||||
if d := itemDatatype(t); d != first {
|
||||
return first, disagreement(items[0], first, t, d)
|
||||
}
|
||||
}
|
||||
return first, nil
|
||||
return itemDatatype(items[0])
|
||||
}
|
||||
|
||||
// itemDatatype is the datatype a column item declares, else that of the column it is.
|
||||
// itemDatatype is the datatype a column item declares, else that of the column it reads.
|
||||
func itemDatatype(t *template) DataType {
|
||||
if t.datatype != DataTypeString {
|
||||
return t.datatype
|
||||
if t.datatype == DataTypeString && t.readsColumn != nil {
|
||||
return columnDatatype(t.readsColumn.column)
|
||||
}
|
||||
return readDatatype(t)
|
||||
}
|
||||
|
||||
// readDatatype is the datatype of the column t is, reading it by one reference alone; a string
|
||||
// when t reads none.
|
||||
func readDatatype(t *template) DataType {
|
||||
if t.readsColumn == nil {
|
||||
return DataTypeString
|
||||
}
|
||||
items, _ := columnItems(t.readsColumn.column)
|
||||
if len(items) == 0 {
|
||||
return DataTypeString
|
||||
}
|
||||
return itemDatatype(items[0]) // checkColumns refuses that column where its items disagree
|
||||
return t.datatype
|
||||
}
|
||||
|
||||
// columnItems is a column's template items, its choices unwrapped, and whether one is null.
|
||||
|
||||
@@ -254,8 +254,7 @@ func recordOf(n node) (*template, []Column, error) {
|
||||
}
|
||||
columns := make([]Column, len(names))
|
||||
for i, name := range names {
|
||||
datatype, _ := columnDatatype(t.fields[name]) // checkColumns refused items that disagree wherever DataType is read
|
||||
columns[i] = Column{Name: name, DataType: datatype}
|
||||
columns[i] = Column{Name: name, DataType: columnDatatype(t.fields[name])}
|
||||
}
|
||||
return t, columns, nil
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ Self-sufficiency 5.6), every seat capped by Locality, and all nine naming
|
||||
|
||||
This round, in order:
|
||||
|
||||
- Derive a column's datatype in one place: `columnItems` yields nothing for a
|
||||
`tableColumn`, and six callers re-derive it from items.
|
||||
- Give `head`, `index`, `bound` and `draw` one meaning each, name `table.family`
|
||||
for the root it returns, and replace the token kind bytes `'l'`, `'t'`, `'f'` and
|
||||
`'b'`, whose `'l'` means different things in `ftoken` and `formatToken`.
|
||||
|
||||
@@ -34,8 +34,8 @@ func (p *valueProof) checkDatatype(path string, n node) error {
|
||||
if !ok || t.datatype == DataTypeString {
|
||||
return nil
|
||||
}
|
||||
if d := readDatatype(t); d == t.datatype {
|
||||
return fmt.Errorf(`%s: %s takes datatype %s from the column it reads; drop "datatype"`, path, t.format, d)
|
||||
if r := t.readsColumn; r != nil && columnDatatype(r.column) == t.datatype {
|
||||
return fmt.Errorf(`%s: %s takes datatype %s from the column it reads; drop "datatype"`, path, t.format, t.datatype)
|
||||
}
|
||||
if reason := p.proveColumnItem(t).not[t.datatype]; reason != "" {
|
||||
return fmt.Errorf("%s: datatype %s: %s", path, t.datatype, reason)
|
||||
|
||||
Reference in New Issue
Block a user