コード例 #1
0
ファイル: binlog_parser.go プロジェクト: shrutip/vitess
//This parses the stream comment.
func parseStreamComment(dmlComment string, autoincId uint64) (EventNode *parser.Node) {
	EventNode = parser.NewSimpleParseNode(parser.NODE_LIST, "")

	tokenizer := parser.NewStringTokenizer(dmlComment)
	var node *parser.Node
	var pkTuple *parser.Node

	node = tokenizer.Scan()
	if node.Type == parser.ID {
		//Table Name
		EventNode.Push(node)
	}

	for node = tokenizer.Scan(); node.Type != ';'; node = tokenizer.Scan() {
		switch node.Type {
		case '(':
			//pkTuple is a list of pk value Nodes
			pkTuple = parsePkTuple(tokenizer, &autoincId)
			EventNode.Push(pkTuple)
		default:
			panic(NewBinlogParseError(EVENT_ERROR, fmt.Sprintf("Error in parsing stream comment: illegal node type %v %v", node.Type, string(node.Value))))
		}
	}

	return EventNode
}
コード例 #2
0
ファイル: event_streamer.go プロジェクト: ninqing/vitess
// Example query: insert into vtocc_e(foo) values ('foo') /* _stream vtocc_e (eid id name ) (null 1 'bmFtZQ==' ); */
// the "null" value is used for auto-increment columns.
func parseStreamComment(dmlComment string) (eventNode EventNode, err error) {
	tokenizer := sqlparser.NewStringTokenizer(dmlComment)

	typ, val := tokenizer.Scan()
	if typ != sqlparser.ID {
		return eventNode, fmt.Errorf("expecting table name in stream comment")
	}
	eventNode.Table = string(val)

	eventNode.Columns, err = parsePkNames(tokenizer)
	if err != nil {
		return eventNode, err
	}

	for typ, val = tokenizer.Scan(); typ != ';'; typ, val = tokenizer.Scan() {
		switch typ {
		case '(':
			// pkTuple is a list of pk value Nodes
			pkTuple, err := parsePkTuple(tokenizer)
			if err != nil {
				return eventNode, err
			}
			eventNode.Tuples = append(eventNode.Tuples, pkTuple)
		default:
			return eventNode, fmt.Errorf("expecting '('")
		}
	}

	return eventNode, nil
}
コード例 #3
0
ファイル: event_streamer.go プロジェクト: nimishzynga/vitess
// Example query: insert into vtocc_e(foo) values ('foo') /* _stream vtocc_e (eid id name ) (null 1 'bmFtZQ==' ); */
// the "null" value is used for auto-increment columns.
func parseStreamComment(dmlComment string) (EventNode *sqlparser.Node, err error) {
	EventNode = sqlparser.NewSimpleParseNode(sqlparser.NODE_LIST, "")
	tokenizer := sqlparser.NewStringTokenizer(dmlComment)

	node := tokenizer.Scan()
	if node.Type != sqlparser.ID {
		return nil, fmt.Errorf("expecting table name in stream comment")
	}
	EventNode.Push(node)

	for node = tokenizer.Scan(); node.Type != ';'; node = tokenizer.Scan() {
		switch node.Type {
		case '(':
			// pkTuple is a list of pk value Nodes
			pkTuple, err := parsePkTuple(tokenizer)
			if err != nil {
				return nil, err
			}
			EventNode.Push(pkTuple)
		default:
			return nil, fmt.Errorf("expecting '('")
		}
	}

	return EventNode, nil
}
コード例 #4
0
ファイル: event_streamer.go プロジェクト: jmptrader/vitess
// Example query: insert into _table_(foo) values ('foo') /* _stream _table_ (eid id name ) (null 1 'bmFtZQ==' ); */
// the "null" value is used for auto-increment columns.
func (evs *EventStreamer) buildDMLEvent(sql string, insertid int64) (*binlogdatapb.StreamEvent, int64, error) {
	// first extract the comment
	commentIndex := strings.LastIndex(sql, streamCommentStart)
	if commentIndex == -1 {
		return nil, insertid, fmt.Errorf("missing stream comment")
	}
	dmlComment := sql[commentIndex+streamCommentStartLen:]

	// then strat building the response
	dmlEvent := &binlogdatapb.StreamEvent{
		Category: binlogdatapb.StreamEvent_SE_DML,
	}
	tokenizer := sqlparser.NewStringTokenizer(dmlComment)

	// first parse the table name
	typ, val := tokenizer.Scan()
	if typ != sqlparser.ID {
		return nil, insertid, fmt.Errorf("expecting table name in stream comment")
	}
	dmlEvent.TableName = string(val)

	// then parse the PK names
	var err error
	dmlEvent.PrimaryKeyFields, err = parsePkNames(tokenizer)
	hasNegatives := make([]bool, len(dmlEvent.PrimaryKeyFields))
	if err != nil {
		return nil, insertid, err
	}

	// then parse the PK values, one at a time
	for typ, val = tokenizer.Scan(); typ != ';'; typ, val = tokenizer.Scan() {
		switch typ {
		case '(':
			// pkTuple is a list of pk values
			var pkTuple *querypb.Row
			pkTuple, insertid, err = parsePkTuple(tokenizer, insertid, dmlEvent.PrimaryKeyFields, hasNegatives)
			if err != nil {
				return nil, insertid, err
			}
			dmlEvent.PrimaryKeyValues = append(dmlEvent.PrimaryKeyValues, pkTuple)
		default:
			return nil, insertid, fmt.Errorf("expecting '('")
		}
	}

	return dmlEvent, insertid, nil
}