code: func (p *physicalTableSource) MarshalJSON() ([]byte, error) {
  	buffer := bytes.NewBufferString("{")
  	limit := 0
  	if p.LimitCount != nil {
  		limit = int(*p.LimitCount)
  	}
  	buffer.WriteString(fmt.Sprintf("\"limit\": %d, \n", limit))
  	if p.Aggregated {
  		buffer.WriteString(fmt.Sprint("\"aggregated push down\": true, \n"))
  		gbyItems, err := json.Marshal(p.gbyItems)
  		if err != nil {
  			return nil, errors.Trace(err)
  		}
  		buffer.WriteString(fmt.Sprintf("\"gby items\": %s, \n", gbyItems))
  		aggFuncs, err := json.Marshal(p.aggFuncs)
  		if err != nil {
  			return nil, errors.Trace(err)
  		}
  		buffer.WriteString(fmt.Sprintf("\"agg funcs\": %s, \n", aggFuncs))
  	} else if len(p.sortItems) > 0 {
  		sortItems, err := json.Marshal(p.sortItems)
  		if err != nil {
  			return nil, errors.Trace(err)
  		}
  		buffer.WriteString(fmt.Sprintf("\"sort items\": %s, \n", sortItems))
  	}
  	access, err := json.Marshal(p.AccessCondition)
  	if err != nil {
  		return nil, errors.Trace(err)
  	}
  	indexFilter, err := json.Marshal(p.indexFilterConditions)
  	if err != nil {
  		return nil, errors.Trace(err)
  	}
  	tableFilter, err := json.Marshal(p.tableFilterConditions)
  	if err != nil {
  		return nil, errors.Trace(err)
  	}
  	// print condition infos
  	buffer.WriteString(fmt.Sprintf("\"access conditions\": %s, \n", access))
  	buffer.WriteString(fmt.Sprintf("\"index filter conditions\": %s, \n", indexFilter))
  	buffer.WriteString(fmt.Sprintf("\"table filter conditions\": %s}", tableFilter))
  	return buffer.Bytes(), nil
  }
docs: // MarshalJSON implements json.Marshaler interface.