Permalink
Browse files

Add query.go.

  • Loading branch information...
1 parent f9d02f5 commit cd91b11d9a8e3a968cff950dae4b5a649700e476 @umitanuki committed Jan 28, 2013
Showing with 195 additions and 13 deletions.
  1. +12 −13 src/bigpot/parser/gram.y
  2. +170 −0 src/bigpot/parser/query.go
  3. +9 −0 src/bigpot/relation/relation.go
  4. +4 −0 src/bigpot/system/types.go
View
@@ -12,15 +12,16 @@ type Node interface {
type ResTarget struct {
name string
+ val Node
}
-type ParseTable struct {
+type ColumnRef struct {
name string
}
type SelectStmt struct {
- target []*ResTarget
- from []*ParseTable
+ targetList []*ResTarget
+ fromList []Node
}
var TopList []Node
@@ -81,35 +82,33 @@ statement: SELECT column_list FROM table_list
for i, elem := range $2 {
target[i] = elem.(*ResTarget)
}
- from := make([]*ParseTable, len($4), len($4))
- for i, elem := range $4 {
- from[i] = elem.(*ParseTable)
- }
$$ = &SelectStmt{
- target: target,
- from: from,
+ targetList: target,
+ fromList: $4,
}
}
column_list: IDENT
{
- n := &ResTarget{name: $1}
+ ref := ColumnRef{name: $1}
+ n := &ResTarget{name: $1, val: Node(ref)}
$$ = append(make([]Node, 0), Node(n))
}
| column_list ',' IDENT
{
- n := &ResTarget{name: $3}
+ ref := ColumnRef{name: $3}
+ n := &ResTarget{name: $3, val: Node(ref)}
$$ = append($1, Node(n))
}
table_list: IDENT
{
- n := &ParseTable{name: $1}
+ n := &RangeVar{RelationName: $1}
$$ = append(make([]Node, 0), Node(n))
}
| table_list ',' IDENT
{
- n := &ParseTable{name: $3}
+ n := &RangeVar{RelationName: $3}
$$ = append($1, Node(n))
}
%%
View
@@ -0,0 +1,170 @@
+package parser
+
+import "bigpot/relation"
+import "bigpot/system"
+
+type CommandType int
+const (
+ CMD_SELECT = iota
+ CMD_INSERT
+ CMD_UPDATE
+ CMD_DELETE
+)
+
+type RangeVar struct {
+ SchemaName string
+ RelationName string
+}
+
+type Expr struct {
+ ReturnType system.Oid
+}
+
+type Var struct {
+ Expr
+ VarNo uint16
+ VarAttNo uint16
+}
+
+type TargetEntry struct {
+ Expr *Expr
+ ResNo uint16
+ ResName uint16
+ ResJunk bool
+}
+
+type RteType int
+const (
+ RTE_RELATION = iota
+ RTE_SUBQUERY
+ RTE_JOIN
+ RTE_VALUES
+ RTE_FUNCTION
+ RTE_CTE
+)
+
+type RangeTblEntry struct {
+ RteType RteType
+ /* for relation */
+ relid system.Oid
+}
+
+type Query struct {
+ CommandType CommandType
+ TargetList []*TargetEntry
+ RangeTables []*RangeTblEntry
+}
+
+type Parser interface {
+ Parse(query_string string) *Query
+}
+
+type ParserImpl struct {
+ query string
+ namespace []*RangeTblEntry
+}
+
+type ParserError struct {
+ msg string
+ location int
+}
+
+func (e ParserError) Error() string {
+ return e.msg
+}
+
+func parseError(msg string) error {
+ /* TODO: get stack */
+ return ParserError{msg: msg}
+}
+
+func (parser *ParserImpl) Parse(query_string string) *Query {
+ lexer := newLexer(query_string)
+ yyParse(lexer)
+ query := &Query{}
+
+ return query
+}
+
+func (parser *ParserImpl) transformStmt(node Node) (*Query, error) {
+ switch node.(type) {
+ default:
+ return nil, parseError("unknown node type")
+ case *SelectStmt:
+ return parser.transformSelectStmt(node.(*SelectStmt))
+ }
+ panic("unreachable")
+}
+
+func (parser *ParserImpl) transformSelectStmt(stmt *SelectStmt) (query *Query, err error) {
+ query = &Query{CommandType: CMD_SELECT}
+ err = nil
+ if err = parser.transformFromClause(stmt); err != nil {
+ return
+ }
+ if query.TargetList, err =
+ parser.transformTargetList(stmt.targetList); err != nil {
+ return
+ }
+
+ return
+}
+
+func (parser *ParserImpl) transformFromClause(stmt *SelectStmt) error {
+ for _, item := range stmt.fromList {
+ switch item.(type) {
+ default:
+ return parseError("unknown node type")
+ case *RangeVar:
+ rv := item.(*RangeVar)
+ rte := &RangeTblEntry{}
+ /* TODO: implement relation_open_rv() */
+ relation := RelationOpenRv(rv)
+ rte.relid = relation.RelId
+ /* TODO: make Alias and add it to namespace, not Rte */
+ parser.namespace = append(parser.namespace, rte)
+ }
+ }
+
+ return nil
+}
+
+func (parser *ParserImpl) transformTargetList(targetList []*ResTarget) (tlist []*TargetEntry, err error) {
+ for _, item := range targetList {
+ var tle *TargetEntry
+ tle, err = parser.transformTargetEntry(item)
+ if err != nil {
+ return
+ }
+ tlist = append(tlist, tle)
+ }
+
+ return
+}
+
+func (parser *ParserImpl) transformTargetEntry(restarget *ResTarget) (tle *TargetEntry, err error) {
+ tle = &TargetEntry{}
+ err = nil
+
+ tle.Expr, err = parser.transformExpr(restarget.val)
+
+ return
+}
+
+func (parser *ParserImpl) transformExpr(node Node) (expr *Expr, err error) {
+ switch node.(type) {
+ default:
+ return nil, parseError("unknown node type")
+ case *ColumnRef:
+ /* TODO: Explore namespace and transform to Var */
+
+ }
+
+ panic("unreachable")
+}
+
+func RelationOpenRv(rv *RangeVar) *relation.Relation {
+ rel := &relation.Relation{}
+
+ return rel
+}
@@ -0,0 +1,9 @@
+/* TODO: should this package be in access/common? */
+package relation
+
+import "bigpot/system"
+
+type Relation struct {
+ RelId system.Oid
+}
+
@@ -0,0 +1,4 @@
+package system
+
+type Oid uint32
+type Name string

0 comments on commit cd91b11

Please sign in to comment.