func (this *DmlBase) buildPathCriterias(paths []*PathElement) []*PathCriteria {
	index := 0
	var tableCriterias []*Criteria
	length := len(paths) + 1
	pathCriterias := make([]*PathCriteria, length, length)
	for _, pe := range paths {
		index++
		var pc *PathCriteria
		if pe.Criteria != nil {
			pc = new(PathCriteria)
			pc.Criterias = append(pc.Criterias, pe.Criteria)
			pathCriterias[index] = pc
		}
		tableCriterias = pe.Base.GetTableTo().GetCriterias()
		if tableCriterias != nil {
			if pc == nil {
				pc = new(PathCriteria)
				pathCriterias[index] = pc
			}
			pc.Criterias = append(pc.Criterias, tableCriterias...)
		}
		if pe.Columns != nil {
			if pc == nil {
				pc = new(PathCriteria)
				pathCriterias[index] = pc
			}
			pc.Columns = pe.Columns
		}
	}
	var lastFkAlias = this.GetTableAlias()
	index = 0
	for _, pe := range paths {
		index++
		discriminators := pe.Base.GetDiscriminators()
		if discriminators != nil {
			pc := pathCriterias[index]
			if pc == nil {
				pc = new(PathCriteria)
				pathCriterias[index] = pc
			}
			if pe.Base.GetDiscriminatorTable().Equals(pe.Base.GetTableTo()) {
				for _, v := range discriminators {
					pc.Criterias = append(pc.Criterias, v.Criteria())
				}
			} else {
				for _, v := range discriminators {
					crit := v.Criteria()
					crit.SetTableAlias(lastFkAlias)
					pc.Criterias = append(pc.Criterias, crit)
				}
			}
		}
		lastFkAlias = this.joinBag.GetAlias(pe.Derived)
	}
	return pathCriterias
}
/*
The path criteria on position 0 refers the criteria on the FROM table.
The Association can have a constraint(discriminator) refering a column in the source table.
Both ends of Discriminator criterias (association origin and destination tables) are treated in this block
package db
import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"time"
	"github.com/quintans/goSQL/dbx"
	tk "github.com/quintans/toolkit"
	"github.com/quintans/toolkit/log"
)
var lgr = log.LoggerFor("github.com/quintans/goSQL/db")
type RawSql struct {
	OriSql string
	Sql string
	Names []string
}
func (this *RawSql) BuildValues(paramMap map[string]interface{}) []interface{} {
	paramArray := make([]interface{}, len(this.Names))
	var ok bool
	for i, name := range this.Names {
		paramArray[i], ok = paramMap[name]
		if !ok {
			panic(fmt.Sprintf("[%s] No value supplied for the SQL parameter '%s' for the SQL %s",
				dbx.FAULT_VALUES_STATEMENT, name, this.OriSql))
		}
	}
	return paramArray
}
func (this *RawSql) Clone() interface{} {
	other := new(RawSql)
	other.OriSql = this.OriSql
	other.Sql = this.Sql
	if this.Names != nil {
		other.Names = make([]string, len(this.Names))
		copy(other.Names, this.Names)
	}
	return other
}
type PathCriteria struct {
	Criterias []*Criteria
	Columns   []Tokener
}
const JOIN_PREFIX = "j"
const PREFIX = "t"
type DmlBase struct {
	db IDb
	table                  *Table
	tableAlias             string
	joins                  []*Join
	criteria               *Criteria
	parameters             map[string]interface{}
	joinBag                *AliasBag
	lastFkAlias            string
	lastJoin               *Join
	discriminatorCriterias []*Criteria
	rawIndex               int
	cachedAssociation [][]*PathElement
	path []*PathElement
	rawSQL *RawSql
	dba    *dbx.SimpleDBA
}
func NewDmlBase(DB IDb, table *Table) *DmlBase {
	this := new(DmlBase)
	this.Super(DB, table)
	return this
}
func (this *DmlBase) Super(DB IDb, table *Table) {
	this.db = DB
	this.table = table
	this.alias(PREFIX + "0")
	if table != nil {
		this.discriminatorCriterias = table.GetCriterias()
	}
	this.parameters = make(map[string]interface{})
	this.dba = dbx.NewSimpleDBA(DB.GetConnection())
}
func (this *DmlBase) NextRawIndex() int {
	this.rawIndex++
	return this.rawIndex
}
func (this *DmlBase) GetDb() IDb {
	return this.db
}
func (this *DmlBase) GetDba() *dbx.SimpleDBA {
	return this.dba
}
func (this *DmlBase) GetTable() *Table {
	return this.table
}
func (this *DmlBase) GetTableAlias() string {
	return this.tableAlias
}
func (this *DmlBase) SetTableAlias(alias string) {
	this.alias(alias)
}
func (this *DmlBase) alias(a string) {
	if a != "" {
		this.joinBag = NewAliasBag(a + "_" + JOIN_PREFIX)
		this.tableAlias = a
		this.rawSQL = nil
	}
}
func (this *DmlBase) GetJoins() []*Join {
	return this.joins
}
func (this *DmlBase) SetParameter(key string, parameter interface{}) {
	this.parameters[key] = parameter
}
func (this *DmlBase) GetParameters() map[string]interface{} {
	return this.parameters
}
func (this *DmlBase) GetParameter(column *Column) interface{} {
	return this.parameters[column.GetAlias()]
}
func (this *DmlBase) GetCriteria() *Criteria {
	return this.criteria
}
func (this *DmlBase) SetParameterFor(col *Column, parameter interface{}) {
	this.SetParameter(col.GetAlias(), parameter)
}
func (this *DmlBase) GetAliasForAssociation(association *Association) string {
	if this.joinBag != nil {
		return this.joinBag.GetAlias(association)
	}
	return ""
}
func (this *DmlBase) inner(inner bool, associations ...*Association) {
	for _, association := range associations {
		pe := new(PathElement)
		pe.Base = association
		pe.Inner = inner
		this.path = append(this.path, pe)
	}
	this.rawSQL = nil
}
func (this *DmlBase) joinTo(path []*PathElement, fetch bool) {
	if len(path) > 0 {
		this.addJoin(path, nil, fetch)
		pathCriterias := this.buildPathCriterias(path)
		var firstCriterias []*Criteria
		for index, pathCriteria := range pathCriterias {
			if pathCriteria != nil {
				conds := pathCriteria.Criterias
				if conds != nil {
					if index == 0 {
						firstCriterias = conds
					} else {
						if firstCriterias != nil {
							tmp := make([]*Criteria, len(conds))
							copy(tmp, conds)
							conds = append(tmp, firstCriterias...)
							firstCriterias = nil
						}
						this.applyOn(path[:index], And(conds...))
					}
				}
				if pathCriteria.Columns != nil {
					this.applyInclude(path[:index], pathCriteria.Columns...)
				}
			}
		}
	}
}