Permalink
Browse files

get select into parsing again

  • Loading branch information...
1 parent e10139c commit dabe9f48e6858bc4bc5ec22ff30ad9efd5a9f0b6 @JakeWheat committed Oct 29, 2011
View
29 bigplan
@@ -28,12 +28,41 @@ typesafe wrapper, use for chaos tests, get chaos actually running also
type checking flow, inferred type ish
+
+= current work: typechecking fixes:
+
+do syntax fix first - into, split plpgsql statement types from regular
+sql?
+
+get rid of inftype in annotation
+get rid of almost all the typechecking code completely
+adjust the catalog to use names (and handle case properly, maybe
+ better error checking also?)
+start with simple scalar expressions: get types, and type errors
+then add fns and fnprototype annotation
+and ability to get type of ? via attrs
+
+then start on queryexprs:
+simple trefs, simple select lists
+* expansion
+build up to all trefs
+
+other query expr parts ...
+then dml
+then have ddl and plpgsql to tackle
+
+get to stage where chaos can successfully type check
+will be a lot more functional that current system at this point
+
+
+
concrete steps:
2) rewrite the parse tests to be readable
3) kill the typechecking, and start again with better annotation
4) work through the typechecking tests getting the new system working
5) look at typechecking chaos
+
Details
@@ -33,16 +33,20 @@
> [Perform ea $ FunCall ea (name "test") [
> FunCall ea (name "||") [eqi "r" "relvar_name"
> ,stringQ "_and_stuff"]]]
-> -- FIXME: get into working again
-> -- This should be in the plpgsql section
-> {-,f "select into a,b c,d from e;"
-> [Into ea False [ei "a", ei "b"]
+> ,f "select into a,b c,d from e;"
+> [Into ea False [name "a", name "b"]
> $ QueryStatement ea $ Select ea Dupes (SelectList ea [selI "c", selI "d"])
-> [Tref ea (i "e") (NoAlias ea)] Nothing [] Nothing [] Nothing Nothing]-}
-> {-,f "select c,d into a,b from e;"
-> [Into ea False [ei "a", ei "b"]
+> [Tref ea (i "e") (NoAlias ea)] Nothing [] Nothing [] Nothing Nothing]
+> ,f "select c,d into a,b from e;"
+> [Into ea False [name "a", name "b"]
> $ QueryStatement ea $ Select ea Dupes (SelectList ea [selI "c", selI "d"])
-> [Tref ea (i "e") (NoAlias ea)] Nothing [] Nothing [] Nothing Nothing]-}
+> [Tref ea (i "e") (NoAlias ea)] Nothing [] Nothing [] Nothing Nothing]
+> ,f "delete from pieces where x = 1 and y = 1 returning tag into r.tag;"
+> [Into ea False [Name ea [Nmc "r",Nmc "tag"]]
+> $ Delete ea (dqi "pieces") []
+> (Just $ funCall "!and" [funCall "=" [ei "x",num "1"]
+> ,funCall "=" [ei "y",num "1"]])
+> (Just $ sl [selI "tag"])]
> ,f "update pieces\n\
> \set a=b returning tag into r.tag;"
> [Into ea False [Name ea [Nmc "r",Nmc "tag"]]
@@ -236,33 +236,43 @@ this recursion needs refactoring cos it's a mess
> intoQueryStatement :: SParser Statement
> intoQueryStatement = do
-> p <- pos
-> (i,q) <- pQueryExprX True
-> return $ i $ QueryStatement p q
+> (i,_) <- pQueryExprX True
+> case i of
+> Nothing -> fail "not into"
+> Just s -> return s
> pQueryExpr :: SParser QueryExpr
> pQueryExpr = snd <$> pQueryExprX False
-> pQueryExprX :: Bool -> SParser (Statement -> Statement, QueryExpr)
-> pQueryExprX allowInto = (id,) <$>
-> (with <|>
-> buildExpressionParser combTable selFactor)
+bit convoluted to parse the into part
+
+> pQueryExprX :: Bool -> SParser (Maybe Statement, QueryExpr)
+> pQueryExprX allowInto =
+> ((Nothing,) <$> with)
+> <|> buildExpressionParser combTable selFactor
> where
-> selFactor = try (parens pQueryExpr) <|> selQuerySpec <|> values
+> selFactor = choice [try ((Nothing,) <$> (parens pQueryExpr))
+> ,selQuerySpec
+> ,(Nothing,) <$> values]
> with = WithQueryExpr <$> (pos <* keyword "with")
> <*> commaSep1 withQuery
> <*> pQueryExpr
> withQuery = WithQuery <$> pos
> <*> nameComponent
> <*> tryOptionMaybe (parens $ commaSep nameComponent)
> <*> (keyword "as" *> parens pQueryExpr)
-> combTable = [map (\(c,p) -> Infix (CombineQueryExpr
-> <$> pos
-> <*> (c <$ p)) AssocLeft)
-> [(Except, keyword "except")
-> ,(Intersect, keyword "intersect")
-> ,(UnionAll, try (keyword "union" *> keyword "all"))
-> ,(Union, keyword "union")]]
+> combTable =
+> [map makeOp [(Except, keyword "except")
+> ,(Intersect, keyword "intersect")
+> ,(UnionAll, try (keyword "union" *> keyword "all"))
+> ,(Union, keyword "union")]]
+> makeOp (c,p) =
+> Infix (do
+> cmb <- CombineQueryExpr
+> <$> pos
+> <*> (c <$ p)
+> return $ \s0 s1 -> (Nothing, cmb (snd s0) (snd s1))
+> ) AssocLeft
> selQuerySpec = do
> p <- pos <* keyword "select"
> d <- option Dupes (Distinct <$ keyword "distinct")
@@ -272,19 +282,23 @@ this recursion needs refactoring cos it's a mess
> $ keyword "top" *> (NumberLit <$> pos <*> (show <$> integer))
> -- todo: work out how to make this work properly - need to return
> -- the into
-> (sl,_intoBit) <- if allowInto
+> (sl,intoBit) <- if allowInto
> then permute ((,)
> <$$> try selectList
> <|?> (Nothing, Just <$> into))
-> else (,Nothing) <$> selectList
-> Select p d sl
+> else (,Nothing) <$> selectList
+> s <- Select p d sl
> <$> option [] from
> <*> optionMaybe whereClause
> <*> option [] groupBy
> <*> optionMaybe having
> <*> orderBy
> <*> option tp (Just <$> limit)
> <*> optionMaybe offset
+> return (case intoBit of
+> Just f -> Just $ f $ QueryStatement p s
+> Nothing -> Nothing
+> ,s)
> from = keyword "from" *> commaSep1 tableRef
> groupBy = keyword "group" *> keyword "by"
> *> commaSep1 expr
@@ -46,7 +46,7 @@ Public functions
>
> printQueryExpr :: QueryExpr -> String
-> printQueryExpr ast = render (queryExpr False True True ast <> statementEnd True)
+> printQueryExpr ast = render (queryExpr False True True Nothing ast <> statementEnd True)
> -- | Testing function, pretty print an expression
> printScalarExpr :: ScalarExpr -> String
@@ -56,7 +56,7 @@ Public functions
> -- | Try harder to make the output human readable, not necessary correct
> -- sql output at the moment
> printQueryExprNice :: QueryExpr -> String
-> printQueryExprNice ast = render (queryExpr True True True ast <> statementEnd True)
+> printQueryExprNice ast = render (queryExpr True True True Nothing ast <> statementEnd True)
-------------------------------------------------------------------------------
@@ -72,15 +72,15 @@ Conversion routines - convert Sql asts into Docs
>
> statement nice se ca (QueryStatement ann s) =
> annot ca ann <+>
-> queryExpr nice True True s <> statementEnd se
+> queryExpr nice True True Nothing s <> statementEnd se
>
> --dml
>
> statement nice se pa (Insert ann tb atts idata rt) =
> annot pa ann <+>
> text "insert into" <+> name tb
> <+> ifNotEmpty (parens . sepCsvMap nmc) atts
-> $+$ queryExpr nice True True idata
+> $+$ queryExpr nice True True Nothing idata
> $+$ returning nice rt
> <> statementEnd se
>
@@ -168,7 +168,7 @@ Conversion routines - convert Sql asts into Docs
> annot ca ann <+>
> text "create table"
> <+> name t <+> text "as"
-> $+$ queryExpr nice True True sel
+> $+$ queryExpr nice True True Nothing sel
> <> statementEnd se
>
> statement nice se ca (CreateFunction ann nm args retType rep lang body vol) =
@@ -224,7 +224,7 @@ Conversion routines - convert Sql asts into Docs
> Nothing -> empty
> Just cs -> parens (sepCsvMap nmc cs)
> <+> text "as"
-> $+$ nest 2 (queryExpr nice True True sel) <> statementEnd se
+> $+$ nest 2 (queryExpr nice True True Nothing sel) <> statementEnd se
>
> statement nice se ca (CreateDomain ann nm tp n ex) =
> annot ca ann <+>
@@ -301,7 +301,10 @@ Conversion routines - convert Sql asts into Docs
> <+> maybe empty text lb <> statementEnd se
>
-> statement _ _se _ca (Into _ann _str _into (QueryStatement _annq _s)) = error "no select into"
+> statement nice se ca (Into ann str is (QueryStatement _ q)) =
+> annot ca ann <+>
+> queryExpr nice True True (Just (str,is)) q <> statementEnd se
+
> statement nice se ca (Into ann str into st) =
> annot ca ann <+>
@@ -329,7 +332,7 @@ Conversion routines - convert Sql asts into Docs
> statement nice se ca (ReturnQuery ann sel) =
> annot ca ann <+>
> text "return" <+> text "query"
-> <+> queryExpr nice True True sel <> statementEnd se
+> <+> queryExpr nice True True Nothing sel <> statementEnd se
>
> statement nice se ca (Raise ann rt st exps) =
> annot ca ann <+>
@@ -346,7 +349,7 @@ Conversion routines - convert Sql asts into Docs
> annot ca ann <+>
> label lb <>
> text "for" <+> nmc i <+> text "in"
-> <+> queryExpr nice True True sel <+> text "loop"
+> <+> queryExpr nice True True Nothing sel <+> text "loop"
> $+$ nestedStatements nice ca stmts
> $+$ text "end loop" <> statementEnd se
>
@@ -457,15 +460,20 @@ Statement components
> -- selects
>
-> queryExpr :: Bool -> Bool -> Bool -> QueryExpr -> Doc
-> queryExpr nice writeSelect _ (Select _ dis l tb wh grp hav
-> order lim off) =
+> queryExpr :: Bool -> Bool -> Bool -> Maybe (Bool,[Name]) -> QueryExpr -> Doc
+> queryExpr nice writeSelect _ intoi (Select _ dis l tb wh grp hav
+> order lim off) =
> (text (if writeSelect then "select" else "")
> <+> (case dis of
> Dupes -> empty
> Distinct -> text "distinct"))
> $+$ nest 2 (vcat $ catMaybes
-> [Just $ nest 2 $ selectList nice l
+> [fmap (\(str,is) -> text "into"
+> <+> (if str
+> then text "strict"
+> else empty)
+> <+> sepCsvMap name is) intoi
+> ,Just $ nest 2 $ selectList nice l
> ,Just $ if null tb
> then empty
> else text "from" $+$ nest 2 (sepCsvMap (tref nice) tb)
@@ -479,27 +487,27 @@ Statement components
> ,flip fmap off $ \offs -> text "offset" <+> scalExpr nice offs
> ])
>
-> queryExpr nice writeSelect topLev (CombineQueryExpr _ tp s1 s2) =
-> let p = queryExpr nice writeSelect False s1
+> queryExpr nice writeSelect topLev _ (CombineQueryExpr _ tp s1 s2) =
+> let p = queryExpr nice writeSelect False Nothing s1
> $+$ (case tp of
> Except -> text "except"
> Union -> text "union"
> UnionAll -> text "union" <+> text "all"
> Intersect -> text "intersect")
-> $+$ queryExpr nice True False s2
+> $+$ queryExpr nice True False Nothing s2
> in if topLev then p else parens p
-> queryExpr nice _ _ (Values _ expss) =
+> queryExpr nice _ _ _ (Values _ expss) =
> text "values" $$ nest 2 (vcat $ csv $ map (parens . csvExp nice) expss)
-> queryExpr nice _ _ (WithQueryExpr _ wqs ex) =
+> queryExpr nice _ _ _ (WithQueryExpr _ wqs ex) =
> text "with" $$ nest 2 (vcat $ csv $ map pwq wqs)
-> $+$ queryExpr nice True False ex
+> $+$ queryExpr nice True False Nothing ex
> where
> pwq (WithQuery _ nm cs ex1) =
> nmc nm <> case cs of
> Nothing -> empty
> Just cs' -> parens $ sepCsvMap nmc cs'
> <+> text "as"
-> <+> parens (queryExpr nice True False ex1)
+> <+> parens (queryExpr nice True False Nothing ex1)
> name :: Name -> Doc
> name (Name _ ns) = nmcs ns
@@ -541,7 +549,7 @@ Statement components
> text "using" <+> parens (sepCsvMap nmc ids)
>
> tref nice (SubTref _ sub alias) =
-> parens (queryExpr nice True True sub)
+> parens (queryExpr nice True True Nothing sub)
> <+> text "as" <+> trefAlias nice alias
> tref nice (FunTref _ f@(FunCall _ _ _) a) = scalExpr nice f <+> trefAlias nice a
> tref _nice (FunTref _ x _) =
@@ -724,14 +732,14 @@ Statement components
> scalExpr nice att <+> (if not t then text "not" else empty) <+> text "in"
> <+> parens (case lst of
> InList _ expr -> csvExp nice expr
-> InQueryExpr _ sel -> queryExpr nice True True sel)
+> InQueryExpr _ sel -> queryExpr nice True True Nothing sel)
> scalExpr nice (LiftOperator _ op flav args) =
> scalExpr nice (head args) <+> text op
> <+> text (case flav of
> LiftAny -> "any"
> LiftAll -> "all")
> <+> parens (scalExpr nice $ head $ tail args)
-> scalExpr nice (ScalarSubQuery _ s) = parens (queryExpr nice True True s)
+> scalExpr nice (ScalarSubQuery _ s) = parens (queryExpr nice True True Nothing s)
> scalExpr _ (NullLit _) = text "null"
> scalExpr nice (WindowFn _ fn part order frm) =
> scalExpr nice fn <+> text "over"
@@ -780,7 +788,7 @@ Statement components
> scalExpr _ (PositionalArg _ a) = text "$" <> integer a
> scalExpr _ (Placeholder _) = text "?"
> scalExpr nice (Exists _ s) =
-> text "exists" <+> parens (queryExpr nice True True s)
+> text "exists" <+> parens (queryExpr nice True True Nothing s)
> scalExpr nice (Cast _ ex t) = text "cast" <> parens (scalExpr nice ex
> <+> text "as"
> <+> typeName t)

0 comments on commit dabe9f4

Please sign in to comment.