예제 #1
0
func MoveSeparableExpressionToDataSource(dataSource planner.DataSource, joiner planner.Joiner, sep parser.Expression, rest parser.Expression) bool {
	newFilterExpression := sep
	// get the existing filter (if any)
	filterExpression := dataSource.GetFilter()
	if filterExpression != nil {
		// build an AND expression with sep and the existing
		newFilterExpression = parser.NewAndExpression(sep, filterExpression)

	}

	err := dataSource.SetFilter(newFilterExpression)
	if err != nil {
		// this data source doesn't support this filter
		// continue once this becomes a loop
		//log.Printf("Datasource rejected the new filter expression, %v", err)
		return false
	} else {
		// it accepted the filter, now we just updated the join condition
		err := joiner.SetCondition(rest)
		if err != nil {
			// hmmn, now joiner rejected its new condition
			// we must back out the other change
			//log.Printf("Datasource accepted, but now joiner rejected new filter expression, trying to reset")
			err := dataSource.SetFilter(filterExpression)
			if err != nil {
				log.Fatalf("Datasource rejected setting its filter back to the original value, I don't know what to do")
			}
			return false
		}
	}
	return true
}
예제 #2
0
func LookForSeparableExpression(expr parser.Expression) (parser.Expression, parser.Expression) {
	count := NumberOfDataSourcesReferencedInExpression(expr)
	if count < 2 {
		// all symbols in this expression refer to the same datasource
		// it could be moved out
		return expr, nil
	} else {
		// this expression refers to symbols in 2 or more datasources
		// it cannot be moved itself, but we may have to consier sub-expressions
		and_expr, ok := expr.(*parser.AndExpression)
		if ok {
			// this expression is an AND expression so we can consider moving out
			// its pieces
			sep, remaining := LookForSeparableExpression(and_expr.Left)
			if sep != nil {
				// we found someting to remove
				if remaining == nil {
					// nothing remaining, return RHS
					return sep, and_expr.Right
				} else {
					// build a new AND expression with the remaining piece and the RHS
					return sep, parser.NewAndExpression(remaining, and_expr.Right)
				}
			} else {
				// didn't find anything to remove, try the RHS
				sep, remaining := LookForSeparableExpression(and_expr.Right)
				if sep != nil {
					// we found someting to remove
					if remaining == nil {
						// nothing left, return LHS
						return sep, and_expr.Left
					} else {
						// build a new AND expression with the remaining piece and the RHS
						return sep, parser.NewAndExpression(and_expr.Left, remaining)
					}
				}
			}
		}
	}
	// not an AND expression, nothing more we can do
	return nil, nil
}
예제 #3
0
파일: parser_test.go 프로젝트: mschoch/tuq
var oneSymbolExpressions = []parser.Expression{
	parser.NewProperty("bob"),
	parser.NewArrayLiteral(parser.ExpressionList{parser.NewProperty("bob")}),
	parser.NewObjectLiteral(parser.Object{"field": parser.NewProperty("bob")}),
	parser.NewNotExpression(parser.NewProperty("bob")),
	parser.NewBracketMemberExpression(parser.NewProperty("bob"), parser.NewIntegerLiteral(0)),
}

var twoSymbolExpressions = []parser.Expression{
	parser.NewPlusExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewMinusExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewMultiplyExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewDivideExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewOrExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewAndExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewLessThanExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewLessThanOrEqualExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewGreaterThanExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewGreaterThanOrEqualExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewEqualsExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
	parser.NewNotEqualsExpression(parser.NewProperty("bob"), parser.NewProperty("jay")),
}

var threeSymbolExpressions = []parser.Expression{
	parser.NewTernaryExpression(parser.NewProperty("bob"), parser.NewProperty("jay"), parser.NewProperty("cat")),
}

func TestSymbolsReferenced(t *testing.T) {

	for _, v := range zeroSymbolExpressions {
예제 #4
0
파일: y.go 프로젝트: mschoch/tuq
func yyParse(yylex yyLexer) int {
	var yyn int
	var yylval yySymType
	var yyVAL yySymType
	yyS := make([]yySymType, yyMaxDepth)

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	yystate := 0
	yychar := -1
	yyp := -1
	goto yystack

ret0:
	return 0

ret1:
	return 1

yystack:
	/* put a state and value onto the stack */
	if yyDebug >= 4 {
		fmt.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate))
	}

	yyp++
	if yyp >= len(yyS) {
		nyys := make([]yySymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
	}
	yyS[yyp] = yyVAL
	yyS[yyp].yys = yystate

yynewstate:
	yyn = yyPact[yystate]
	if yyn <= yyFlag {
		goto yydefault /* simple state */
	}
	if yychar < 0 {
		yychar = yylex1(yylex, &yylval)
	}
	yyn += yychar
	if yyn < 0 || yyn >= yyLast {
		goto yydefault
	}
	yyn = yyAct[yyn]
	if yyChk[yyn] == yychar { /* valid shift */
		yychar = -1
		yyVAL = yylval
		yystate = yyn
		if Errflag > 0 {
			Errflag--
		}
		goto yystack
	}

yydefault:
	/* default state action */
	yyn = yyDef[yystate]
	if yyn == -2 {
		if yychar < 0 {
			yychar = yylex1(yylex, &yylval)
		}

		/* look through exception table */
		xi := 0
		for {
			if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			yyn = yyExca[xi+0]
			if yyn < 0 || yyn == yychar {
				break
			}
		}
		yyn = yyExca[xi+1]
		if yyn < 0 {
			goto ret0
		}
	}
	if yyn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			yylex.Error("syntax error")
			Nerrs++
			if yyDebug >= 1 {
				fmt.Printf("%s", yyStatname(yystate))
				fmt.Printf("saw %s\n", yyTokname(yychar))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for yyp >= 0 {
				yyn = yyPact[yyS[yyp].yys] + yyErrCode
				if yyn >= 0 && yyn < yyLast {
					yystate = yyAct[yyn] /* simulate a shift of "error" */
					if yyChk[yystate] == yyErrCode {
						goto yystack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if yyDebug >= 2 {
					fmt.Printf("error recovery pops state %d\n", yyS[yyp].yys)
				}
				yyp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if yyDebug >= 2 {
				fmt.Printf("error recovery discards %s\n", yyTokname(yychar))
			}
			if yychar == yyEofCode {
				goto ret1
			}
			yychar = -1
			goto yynewstate /* try again in the same state */
		}
	}

	/* reduction by production yyn */
	if yyDebug >= 2 {
		fmt.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
	}

	yynt := yyn
	yypt := yyp
	_ = yypt // guard against "declared and not used"

	yyp -= yyR2[yyn]
	yyVAL = yyS[yyp+1]

	/* consult goto table to find next state */
	yyn = yyR1[yyn]
	yyg := yyPgo[yyn]
	yyj := yyg + yyS[yyp].yys + 1

	if yyj >= yyLast {
		yystate = yyAct[yyg]
	} else {
		yystate = yyAct[yyj]
		if yyChk[yystate] != -yyn {
			yystate = yyAct[yyg]
		}
	}
	// dummy call; replaced with literal code
	switch yynt {

	case 1:
		//line tuql.y:36
		{
			logDebugGrammar("INPUT")
		}
	case 3:
		//line tuql.y:40
		{
			logDebugGrammar("PRAGMA: %v", yyS[yypt-3])
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			parser.ProcessPragma(left.(parser.Expression), right.(parser.Expression))
		}
	case 4:
		//line tuql.y:47
		{
			logDebugGrammar("SELECT_STMT")
			parsingQuery.ParsedSuccessfully = true
		}
	case 6:
		//line tuql.y:52
		{
			parsingQuery.IsExplainOnly = true
		}
	case 12:
		//line tuql.y:64
		{
			thisExpression := parsingStack.Pop()
			parsingQuery.Limit = thisExpression.(parser.Expression)
		}
	case 13:
		//line tuql.y:69
		{
			thisExpression := parsingStack.Pop()
			parsingQuery.Offset = thisExpression.(parser.Expression)
		}
	case 16:
		//line tuql.y:78
		{
			thisExpression := parser.NewSortItem(parsingStack.Pop().(parser.Expression), true)
			parsingQuery.Orderby = append(parsingQuery.Orderby, *thisExpression)
		}
	case 17:
		//line tuql.y:81
		{
			thisExpression := parser.NewSortItem(parsingStack.Pop().(parser.Expression), true)
			parsingQuery.Orderby = append(parsingQuery.Orderby, *thisExpression)
		}
	case 18:
		//line tuql.y:84
		{
			thisExpression := parser.NewSortItem(parsingStack.Pop().(parser.Expression), false)
			parsingQuery.Orderby = append(parsingQuery.Orderby, *thisExpression)
		}
	case 19:
		//line tuql.y:89
		{
			logDebugGrammar("SELECT_COMPOUND")
		}
	case 25:
		//line tuql.y:99
		{
			logDebugGrammar("SELECT_CORE")
		}
	case 26:
		//line tuql.y:102
		{
			logDebugGrammar("SELECT GROUP")
			parsingQuery.IsAggregateQuery = true
			parsingQuery.Groupby = parsingStack.Pop().(parser.ExpressionList)
		}
	case 27:
		//line tuql.y:107
		{
			logDebugGrammar("SELECT GROUP HAVING - EMPTY")
		}
	case 28:
		//line tuql.y:108
		{
			logDebugGrammar("SELECT GROUP HAVING - SELECT GROUP")
		}
	case 29:
		//line tuql.y:109
		{
			logDebugGrammar("SELECT GROUP HAVING - SELECT GROUP SELECT HAVING")
		}
	case 30:
		//line tuql.y:114
		{
			parsingQuery.Having = parsingStack.Pop().(parser.Expression)
		}
	case 31:
		//line tuql.y:117
		{
			logDebugGrammar("SELECT WHERE - EMPTY")
		}
	case 32:
		//line tuql.y:118
		{
			logDebugGrammar("SELECT WHERE - EXPR")
			where_part := parsingStack.Pop()
			parsingQuery.Where = where_part.(parser.Expression)
		}
	case 34:
		//line tuql.y:124
		{
			logDebugGrammar("SELECT_FROM")
		}
	case 37:
		//line tuql.y:131
		{
			ds := parser.NewDataSource(yyS[yypt-0].s)
			parsingQuery.AddDataSource(ds)
		}
	case 38:
		//line tuql.y:134
		{
			ds := parser.NewDataSource(yyS[yypt-1].s)
			nextOver := parsingStack.Pop()
			for nextOver != nil {
				ds.AddOver(nextOver.(*parser.Over))
				nextOver = parsingStack.Pop()
			}
			parsingQuery.AddDataSource(ds)
		}
	case 39:
		//line tuql.y:142
		{
			ds := parser.NewDataSourceWithAs(yyS[yypt-2].s, yyS[yypt-0].s)
			parsingQuery.AddDataSource(ds)
		}
	case 40:
		//line tuql.y:145
		{
			ds := parser.NewDataSourceWithAs(yyS[yypt-3].s, yyS[yypt-1].s)
			nextOver := parsingStack.Pop()
			for nextOver != nil {
				ds.AddOver(nextOver.(*parser.Over))
				nextOver = parsingStack.Pop()
			}
			parsingQuery.AddDataSource(ds)
		}
	case 43:
		//line tuql.y:159
		{
			prop := parsingStack.Pop().(*parser.Property)
			over := parser.NewOver(prop, yyS[yypt-0].s)
			parsingStack.Push(over)
		}
	case 45:
		//line tuql.y:167
		{
			logDebugGrammar("SELECT_SELECT")
		}
	case 46:
		//line tuql.y:170
		{
			logDebugGrammar("SELECT_SELECT_HEAD")
		}
	case 49:
		//line tuql.y:175
		{
			logDebugGrammar("SELECT SELECT TAIL - EMPTY")
		}
	case 50:
		//line tuql.y:176
		{
			logDebugGrammar("SELECT SELECT TAIL - EXPR")
			thisExpression := parsingStack.Pop()
			parsingQuery.Sel = thisExpression.(parser.Expression)
		}
	case 51:
		//line tuql.y:182
		{
			logDebugGrammar("EXPRESSION")
		}
	case 52:
		//line tuql.y:183
		{
			logDebugGrammar("EXPRESSION - TERNARY")
			elsee := parsingStack.Pop().(parser.Expression)
			thenn := parsingStack.Pop().(parser.Expression)
			iff := parsingStack.Pop().(parser.Expression)
			thisExpr := parser.NewTernaryExpression(iff, thenn, elsee)
			parsingStack.Push(thisExpr)
		}
	case 53:
		//line tuql.y:192
		{
			logDebugGrammar("EXPR - PLUS")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewPlusExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 54:
		//line tuql.y:198
		{
			logDebugGrammar("EXPR - MINUS")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewMinusExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 55:
		//line tuql.y:204
		{
			logDebugGrammar("EXPR - MULT")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewMultiplyExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 56:
		//line tuql.y:210
		{
			logDebugGrammar("EXPR - DIV")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewDivideExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 57:
		//line tuql.y:216
		{
			logDebugGrammar("EXPR - AND")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewAndExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 58:
		//line tuql.y:222
		{
			logDebugGrammar("EXPR - OR")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewOrExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 59:
		//line tuql.y:228
		{
			logDebugGrammar("EXPR - EQ")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewEqualsExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 60:
		//line tuql.y:234
		{
			logDebugGrammar("EXPR - LT")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewLessThanExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 61:
		//line tuql.y:240
		{
			logDebugGrammar("EXPR - LTE")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewLessThanOrEqualExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 62:
		//line tuql.y:246
		{
			logDebugGrammar("EXPR - GT")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewGreaterThanExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 63:
		//line tuql.y:252
		{
			logDebugGrammar("EXPR - GTE")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewGreaterThanOrEqualExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 64:
		//line tuql.y:258
		{
			logDebugGrammar("EXPR - NE")
			right := parsingStack.Pop()
			left := parsingStack.Pop()
			thisExpression := parser.NewNotEqualsExpression(left.(parser.Expression), right.(parser.Expression))
			parsingStack.Push(thisExpression)
		}
	case 67:
		//line tuql.y:269
		{
			logDebugGrammar("EXPR - NOT")
			curr := parsingStack.Pop().(parser.Expression)
			thisExpression := parser.NewNotExpression(curr)
			parsingStack.Push(thisExpression)
		}
	case 69:
		//line tuql.y:277
		{
			logDebugGrammar("SUFFIX_EXPR")
		}
	case 70:
		//line tuql.y:280
		{
			logDebugGrammar("NULL")
			thisExpression := parser.NewNull()
			parsingStack.Push(thisExpression)
		}
	case 71:
		//line tuql.y:284
		{
		}
	case 72:
		//line tuql.y:285
		{
			logDebugGrammar("ATOM - prop[]")
			rightExpr := parsingStack.Pop().(parser.Expression)
			leftProp := parsingStack.Pop().(*parser.Property)
			thisExpression := parser.NewBracketMemberExpression(leftProp, rightExpr)
			parsingStack.Push(thisExpression)
		}
	case 73:
		//line tuql.y:291
		{
			thisExpression := parser.NewIntegerLiteral(yyS[yypt-0].n)
			parsingStack.Push(thisExpression)
		}
	case 74:
		//line tuql.y:293
		{
			thisExpression := parser.NewIntegerLiteral(-yyS[yypt-1].n)
			parsingStack.Push(thisExpression)
		}
	case 75:
		//line tuql.y:295
		{
			thisExpression := parser.NewFloatLiteral(yyS[yypt-0].f)
			parsingStack.Push(thisExpression)
		}
	case 76:
		//line tuql.y:297
		{
			thisExpression := parser.NewFloatLiteral(-yyS[yypt-1].f)
			parsingStack.Push(thisExpression)
		}
	case 77:
		//line tuql.y:299
		{
			thisExpression := parser.NewStringLiteral(yyS[yypt-0].s)
			parsingStack.Push(thisExpression)
		}
	case 78:
		//line tuql.y:301
		{
			thisExpression := parser.NewBoolLiteral(true)
			parsingStack.Push(thisExpression)
		}
	case 79:
		//line tuql.y:303
		{
			thisExpression := parser.NewBoolLiteral(false)
			parsingStack.Push(thisExpression)
		}
	case 80:
		//line tuql.y:305
		{
			logDebugGrammar("ATOM - {}")
		}
	case 81:
		//line tuql.y:307
		{
			logDebugGrammar("ATOM - []")
			exp_list := parsingStack.Pop().(parser.ExpressionList)
			thisExpression := parser.NewArrayLiteral(exp_list)
			parsingStack.Push(thisExpression)
		}
	case 82:
		//line tuql.y:312
		{
			logDebugGrammar("FUNCTION - $1.s")
			exp_list := parsingStack.Pop().(parser.ExpressionList)
			function := parsingStack.Pop().(*parser.Function)
			function.AddArguments(exp_list)
			parsingStack.Push(function)
		}
	case 85:
		//line tuql.y:322
		{
			logDebugGrammar("EXPRESSION_LIST - EXPRESSION")
			exp_list := make(parser.ExpressionList, 0)
			exp_list = append(exp_list, parsingStack.Pop().(parser.Expression))
			parsingStack.Push(exp_list)
		}
	case 86:
		//line tuql.y:327
		{
			logDebugGrammar("EXPRESSION_LIST - EXPRESSION COMMA EXPRESSION_LIST")
			rest := parsingStack.Pop().(parser.ExpressionList)
			last := parsingStack.Pop()
			new_list := make(parser.ExpressionList, 0)
			new_list = append(new_list, last.(parser.Expression))
			for _, v := range rest {
				new_list = append(new_list, v)
			}
			parsingStack.Push(new_list)
		}
	case 88:
		//line tuql.y:340
		{
			last := parsingStack.Pop().(*parser.ObjectLiteral)
			rest := parsingStack.Pop().(*parser.ObjectLiteral)
			rest.AddAll(last)
			parsingStack.Push(rest)
		}
	case 89:
		//line tuql.y:347
		{
			thisKey := yyS[yypt-2].s
			thisValue := parsingStack.Pop().(parser.Expression)
			thisExpression := parser.NewObjectLiteral(parser.Object{thisKey: thisValue})
			parsingStack.Push(thisExpression)
		}
	case 90:
		//line tuql.y:354
		{
			thisExpression := parser.NewProperty(yyS[yypt-0].s)
			parsingStack.Push(thisExpression)
		}
	case 91:
		//line tuql.y:358
		{
			thisValue := parsingStack.Pop().(*parser.Property)
			thisExpression := parser.NewProperty(yyS[yypt-2].s + "." + thisValue.Symbol)
			parsingStack.Push(thisExpression)
		}
	case 92:
		//line tuql.y:365
		{
			parsingQuery.IsAggregateQuery = true
			thisExpression := parser.NewFunction("min")
			parsingStack.Push(thisExpression)
		}
	case 93:
		//line tuql.y:370
		{
			parsingQuery.IsAggregateQuery = true
			thisExpression := parser.NewFunction("max")
			parsingStack.Push(thisExpression)
		}
	case 94:
		//line tuql.y:375
		{
			parsingQuery.IsAggregateQuery = true
			thisExpression := parser.NewFunction("avg")
			parsingStack.Push(thisExpression)
		}
	case 95:
		//line tuql.y:380
		{
			parsingQuery.IsAggregateQuery = true
			thisExpression := parser.NewFunction("count")
			parsingStack.Push(thisExpression)
		}
	case 96:
		//line tuql.y:385
		{
			parsingQuery.IsAggregateQuery = true
			thisExpression := parser.NewFunction("sum")
			parsingStack.Push(thisExpression)
		}
	}
	goto yystack /* stack new state and value */
}