Repository: dolthub/dolt
File: go/libraries/doltcore/sqle/dtablefunctions/dolt_log.go (Go)

Code before:
}

// DataLength estimates total data size for query planning.
func (ltf *LogTableFunction) DataLength(ctx *sql.Context) (uint64, error) {
	numBytesPerRow := schema.SchemaAvgLength(ltf.Schema())
	numRows, _, err := ltf.RowCount(ctx)
	if err != nil {
		return 0, err
	}
	return numBytesPerRow * numRows, nil
}

// RowCount returns estimated row count for query planning.
func (ltf *LogTableFunction) RowCount(_ *sql.Context) (uint64, bool, error) {
	return logTableDefaultRowCount, false, nil
}

// WithDatabase implements the sql.Databaser interface
func (ltf *LogTableFunction) WithDatabase(database sql.Database) (sql.Node, error) {
	nltf := *ltf
	nltf.database = database
	return &nltf, nil
}

// Name implements the sql.TableFunction interface
func (ltf *LogTableFunction) Name() string {
	return "dolt_log"
}

// Resolved implements the sql.Resolvable interface
func (ltf *LogTableFunction) Resolved() bool {
	// In the new string-based approach, we're resolved when we have argument expressions
	// (which get resolved during normal SQL analysis) or when we have parsed strings
	for _, expr := range ltf.argumentExprs {
		if !expr.Resolved() {
			return false
		}
	}
	return true
}

// IsReadOnly returns true since log operations don't modify data.
func (ltf *LogTableFunction) IsReadOnly() bool {
	return true
}

// String implements the Stringer interface
func (ltf *LogTableFunction) String() string {
	return fmt.Sprintf("DOLT_LOG(%s)", ltf.getOptionsString())
}


Review comment (suggestion):
(minor) super minor, but `Name()` feels more appropriate for being in `LogTableFunction`, instead of `LogTableFunctionArgs`.

Code after:
	for _, revisionStr := range ltfa.revisionStrs {
		if strings.Contains(revisionStr, "..") && (len(ltfa.revisionStrs) > 1 || len(ltfa.notRevisionStrs) > 0) {
			return sql.ErrInvalidArgumentDetails.New(ltfa.Name(), "revision cannot contain '..' or '...' if multiple revisions exist")
		}
	}

	for _, notRevStr := range ltfa.notRevisionStrs {
		if strings.Contains(notRevStr, "..") {
			return sql.ErrInvalidArgumentDetails.New(ltfa.Name(), "--not revision cannot contain '..'")
		}
		if strings.HasPrefix(notRevStr, "^") {
			return sql.ErrInvalidArgumentDetails.New(ltfa.Name(), "--not revision cannot contain '^'")
		}
	}

	return nil
}

// addOptions instantiates a LogTableFunctionArgs by parsing expressions.
func (ltfa *LogTableFunctionArgs) addOptions(ctx *sql.Context, expressions []sql.Expression, parentRow sql.Row, deferExpressions bool) error {
	// TODO: Detect when the schema would change after resolving args.
	var expressionsToParse []sql.Expression
	if deferExpressions {
		for _, expr := range expressions {
			if !isDeferredExpression(expr) {
				expressionsToParse = append(expressionsToParse, expr)
			}
		}
	} else {
		expressionsToParse = expressions
	}

	args, err := getDoltArgs(ctx, expressionsToParse, ltfa.Name(), parentRow)
	if err != nil {
		return err
	}

	apr, err := cli.CreateLogArgParser(true).Parse(args)
	if err != nil {
		return sql.ErrInvalidArgumentDetails.New(ltfa.Name(), err.Error())
	}

	if notRevisionStrs, ok := apr.GetValueList(cli.NotFlag); ok {
		ltfa.notRevisionStrs = append(ltfa.notRevisionStrs, notRevisionStrs...)
	}

	if tableNames, ok := apr.GetValueList(cli.TablesFlag); ok {
		ltfa.tableNames = append(ltfa.tableNames, tableNames...)
	}

	minParents := apr.GetIntOrDefault(cli.MinParentsFlag, 0)