Example #1
0
func (self *TableInfo) initRowCache(conn *DBConnection, cacheSize uint64) {
	if self.PKColumns == nil {
		relog.Warning("Table %s has no primary key. Will not be cached.", self.Name)
		return
	}
	rowInfo, err := conn.ExecuteFetch([]byte(fmt.Sprintf("select * from %s where 1!=1", self.Name)), 10000)
	if err != nil {
		relog.Warning("Failed to fetch column info for %s, table will not be cached: %s", self.Name, err.Error())
		return
	}
	self.Fields = rowInfo.Fields
	self.CacheType = 1
	self.CacheSize = cacheSize
	self.RowCache = cache.NewLRUCache(self.CacheSize)
}
Example #2
0
func (self *TableInfo) fetchIndexes(conn *DBConnection) bool {
	indexes, err := conn.ExecuteFetch([]byte(fmt.Sprintf("show index from %s", self.Name)), 10000)
	if err != nil {
		relog.Warning("%s", err.Error())
		return false
	}
	var currentIndex *schema.Index
	currentName := ""
	for _, row := range indexes.Rows {
		indexName := row[2].(string)
		if currentName != indexName {
			currentIndex = self.AddIndex(indexName)
			currentName = indexName
		}
		currentIndex.AddColumn(row[4].(string))
	}
	if len(self.Indexes) == 0 {
		return true
	}
	pkIndex := self.Indexes[0]
	if pkIndex.Name != "PRIMARY" {
		return true
	}
	self.PKColumns = make([]int, len(pkIndex.Columns))
	for i, pkCol := range pkIndex.Columns {
		self.PKColumns[i] = self.FindColumn(pkCol)
	}
	return true
}
Example #3
0
func Run_server(laddr string) error {
	listen_sock, err := net.Listen("tcp", laddr)
	if err != nil {
		panic(err)
	}

	defer listen_sock.Close()

	sv := new(server)
	store, err := newLeveldb()
	if err != nil {
		panic(err)
	}

	sv.s = store
	sv.kt = make(map[string]chan action)
	sv.lock = new(sync.RWMutex)
	defer store.db.Close()
	for {
		conn, err := listen_sock.Accept()
		if err != nil {
			relog.Warning("%s", err)
			continue
		}

		c := newConn(conn, sv)

		relog.Info("accept successed, client ip is %s", c.remoteAddr)

		go c.serve()
	}
	panic("not reached")
}
Example #4
0
func getPKValues(conditions []*Node, pkIndex *schema.Index) (pkValues []interface{}) {
	if pkIndex.Name != "PRIMARY" {
		relog.Warning("Table has no primary key")
		return nil
	}
	pkIndexScore := NewIndexScore(pkIndex)
	pkValues = make([]interface{}, len(pkIndexScore.ColumnMatch))
	for _, condition := range conditions {
		if condition.Type != '=' && condition.Type != IN {
			return nil
		}
		index := pkIndexScore.FindMatch(string(condition.At(0).Value))
		if index == -1 {
			return nil
		}
		switch condition.Type {
		case '=':
			pkValues[index] = string(condition.At(1).Value)
		case IN:
			pkValues[index], _ = condition.At(1).At(0).parseList()
		}
	}
	if pkIndexScore.GetScore() == 1000 {
		return pkValues
	}
	return nil
}
Example #5
0
func (self *Node) execAnalyzeDelete(getTable TableGetter) (plan *ExecPlan) {
	// Default plan
	plan = &ExecPlan{PlanId: PLAN_PASS_DML, FullQuery: self.GenerateFullQuery()}

	tableName := string(self.At(DELETE_TABLE_OFFSET).Value)
	tableInfo := plan.setTableInfo(tableName, getTable)

	if len(tableInfo.Indexes) == 0 || tableInfo.Indexes[0].Name != "PRIMARY" {
		relog.Warning("no primary key for table %s", tableName)
		plan.Reason = REASON_TABLE_NOINDEX
		return plan
	}

	plan.PlanId = PLAN_DML_SUBQUERY
	plan.OuterQuery = self.GenerateDeleteOuterQuery(tableInfo.Indexes[0])
	plan.Subquery = self.GenerateDeleteSubquery(tableInfo)

	conditions := self.At(DELETE_WHERE_OFFSET).execAnalyzeWhere()
	if conditions == nil {
		plan.Reason = REASON_WHERE
		return plan
	}

	if pkValues := getPKValues(conditions, tableInfo.Indexes[0]); pkValues != nil {
		plan.PlanId = PLAN_DML_PK
		plan.OuterQuery = plan.FullQuery
		plan.PKValues = pkValues
		return plan
	}

	return plan
}
Example #6
0
func StartQueryService(poolSize, transactionCap int, transactionTimeout float64, maxResultSize, queryCacheSize int, schemaReloadTime, queryTimeout, idleTimeout float64) {
	if SqlQueryRpcService != nil {
		relog.Warning("RPC service already up %v", SqlQueryRpcService)
		return
	}
	SqlQueryRpcService = NewSqlQuery(poolSize, transactionCap, transactionTimeout, maxResultSize, queryCacheSize, schemaReloadTime, queryTimeout, idleTimeout)
	rpc.Register(SqlQueryRpcService)
}
Example #7
0
func (self *Node) execAnalyzeInsert(getTable TableGetter) (plan *ExecPlan) {
	plan = &ExecPlan{PlanId: PLAN_PASS_DML, FullQuery: self.GenerateFullQuery()}
	tableName := string(self.At(INSERT_TABLE_OFFSET).Value)
	tableInfo := plan.setTableInfo(tableName, getTable)

	if len(tableInfo.Indexes) == 0 || tableInfo.Indexes[0].Name != "PRIMARY" {
		relog.Warning("no primary key for table %s", tableName)
		plan.Reason = REASON_TABLE_NOINDEX
		return plan
	}

	columns := self.At(INSERT_COLUMN_LIST_OFFSET)
	if columns.Len() == 0 {
		relog.Warning("insert column list not specified for table %s", tableName)
		return plan
	}

	if self.At(INSERT_ON_DUP_OFFSET).Len() != 0 {
		var ok bool
		if plan.SecondaryPKValues, ok = self.At(INSERT_ON_DUP_OFFSET).At(0).execAnalyzeUpdateExpressions(tableInfo.Indexes[0]); !ok {
			plan.Reason = REASON_PK_CHANGE
			return plan
		}
	}

	rowValues := self.At(INSERT_VALUES_OFFSET) // VALUES/SELECT
	if rowValues.Type == SELECT {
		plan.PlanId = PLAN_INSERT_SUBQUERY
		plan.OuterQuery = self.GenerateInsertOuterQuery()
		plan.Subquery = rowValues.GenerateSelectLimitQuery()
		// Column list syntax is a subset of select expressions
		plan.ColumnNumbers = columns.execAnalyzeSelectExpressions(tableInfo)
		plan.SubqueryPKColumns = getPKValuesFromColumns(columns, tableInfo.Indexes[0])
		return plan
	}

	rowList := rowValues.At(0) // VALUES->NODE_LIST
	if pkValues := getInsertPKValues(columns, rowList, tableInfo.Indexes[0]); pkValues != nil {
		plan.PlanId = PLAN_INSERT_PK
		plan.OuterQuery = plan.FullQuery
		plan.PKValues = pkValues
	}
	return plan
}
Example #8
0
func (self *TableInfo) fetchColumns(conn *DBConnection) bool {
	columns, err := conn.ExecuteFetch([]byte(fmt.Sprintf("describe %s", self.Name)), 10000)
	if err != nil {
		relog.Warning("%s", err.Error())
		return false
	}
	for _, row := range columns.Rows {
		self.AddColumn(row[0].(string), row[1].(string))
	}
	return true
}
Example #9
0
func ExecParse(sql string, getTable TableGetter) (plan *ExecPlan, err error) {
	defer handleError(&err)

	tree, err := Parse(sql)
	if err != nil {
		return nil, err
	}
	plan = tree.execAnalyzeSql(getTable)
	if plan.PlanId == PLAN_PASS_DML {
		relog.Warning("PASS_DML: %s", sql)
	}
	return plan, nil
}
Example #10
0
func getInsertPKValues(columns *Node, rowList *Node, pkIndex *schema.Index) (pkValues []interface{}) {
	for i := 0; i < rowList.Len(); i++ {
		if columns.Len() != rowList.At(i).At(0).Len() { // NODE_LIST->'('->NODE_LIST
			panic(NewParserError("number of columns does not match number of values"))
		}
	}

	pkValues = make([]interface{}, len(pkIndex.Columns))
	for i := 0; i < columns.Len(); i++ {
		index := pkIndex.FindColumn(string(columns.At(i).Value))
		if index == -1 {
			continue
		}
		if rowList.Len() == 1 { // simple
			node := rowList.At(0).At(0).At(i) // NODE_LIST->'('->NODE_LIST->Value
			value := node.execAnalyzeValue()
			if value == nil {
				relog.Warning("insert is too complex %v", node)
				return nil
			}
			pkValues[index] = string(value.Value)
		} else { // composite
			values := make([]interface{}, rowList.Len())
			for j := 0; j < rowList.Len(); j++ {
				node := rowList.At(j).At(0).At(i) // NODE_LIST->'('->NODE_LIST->Value
				value := node.execAnalyzeValue()
				if value == nil {
					relog.Warning("insert is too complex %v", node)
					return nil
				}
				values[j] = string(value.Value)
			}
			pkValues[index] = values
		}
	}
	return pkValues
}
Example #11
0
func signal_init() {
	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt)
	go func() {
		for sig := range c {
			switch sig {
			case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
				relog.Warning("Terminating on signal", sig)
				if *cpuprofile != "" {
					pprof.StopCPUProfile()
				}
				os.Exit(0)
			}
		}
	}()
}
Example #12
0
func (self *Node) execAnalyzeUpdateExpressions(pkIndex *schema.Index) (pkValues []interface{}, ok bool) {
	for i := 0; i < self.Len(); i++ {
		columnName := string(self.At(i).At(0).Value)
		if index := pkIndex.FindColumn(columnName); index != -1 {
			value := self.At(i).At(1).execAnalyzeValue()
			if value == nil {
				relog.Warning("expression is too complex %v", self.At(i).At(0))
				return nil, false
			}
			if pkValues == nil {
				pkValues = make([]interface{}, len(pkIndex.Columns))
			}
			pkValues[index] = string(value.Value)
		}
	}
	return pkValues, true
}