001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.couchbase.TUpdateFor;
005import gudusoft.gsqlparser.nodes.teradata.TDataConversion;
006import gudusoft.gsqlparser.nodes.teradata.TDataConversionItem;
007import gudusoft.gsqlparser.sqlenv.TSQLEnv;
008
009import java.util.ArrayList;
010
011import static gudusoft.gsqlparser.sqlenv.ESQLDataObjectType.dotColumn;
012
013/**
014* This class represents select_list item in select statement, lets you specify the columns you want to retrieve from the table.
015 *<p>Syntax:
016 * <blockquote><pre>
017 * query_name|[schema.]{table|view|materialized_view}|expr [ [AS] alias]</pre>
018 * </blockquote>
019 *
020 * 
021 *<p>or, set column values in update_set_clause.
022 *<p>Syntax:
023 *<p><blockquote>column = expr|(subquery) </blockquote>
024 *
025 * <p>or, values clause in insert statement was represented by {@link TResultColumnList}.
026 *<p>Syntax:
027 *<p><blockquote><pre>(expr,expr) </pre></blockquote>
028 *
029*/
030public class TResultColumn extends TNodeWithAliasClause implements Comparable{
031
032
033    // sparksql: select explode(str_to_map(regexp_replace(regexp_replace(regexp_replace(lower(t.input), '', ''), '',''), '', ''), '', '')) as (`key`, `value`) from B t1
034    // select t.a1, t.a2, stack(2, 'T', t.a1, t.a2, t.a3/t.a4, t.a5/t.a6,   'T+0', t.a7, t.a8, t.a9/t.a10, t.a11/t.a12) as (b1, b2, b3, b4, b5)  from db1.table1 t
035    // explode and stack functions are used to convert array or map into rows and create new column names
036    private ArrayList<TObjectName> aliasNameList = null;
037
038    public ArrayList<TObjectName> getAliasNameList() {
039        if (aliasNameList == null) {
040            aliasNameList = new ArrayList<>();
041        }
042        return aliasNameList;
043    }
044
045    private ArrayList<TObjectName> attributesFromUpLevelReferenceToStarColumn;
046
047    /**
048     * 这个属性只对 star column 有效。用来存放在 up level 中找到的关联到本 star column 的 column,
049     * 主要用来把来自 up level 的这些 column 继续和 本层 from clause 中的 table 关联起来,
050     * 以解决 up level column 来自低层哪个 table 的问题
051     *
052     * 实现代码见:TStarColumnPushDownResolver.preVisit(TSelectSqlStatement stmt),
053     * TAttributeNode.addAttributeRefToThisNode(TObjectName objectName)
054     *
055     * @return
056     */
057    public ArrayList<TObjectName> getAttributesFromUpLevelReferenceToStarColumn() {
058        if (attributesFromUpLevelReferenceToStarColumn == null){
059            attributesFromUpLevelReferenceToStarColumn = new ArrayList<>();
060        }
061        return attributesFromUpLevelReferenceToStarColumn;
062    }
063
064    private String aliasName;
065
066    public void setAliasName(String aliasName) {
067        this.aliasName = aliasName;
068    }
069
070    public String getAliasName() {
071        return aliasName;
072    }
073
074    private ArrayList<TReplaceExprAsIdentifier> exprAsIdentifiers;
075
076    /**
077     * BigQuery replace columns
078     * <br>
079     * SELECT * REPLACE (quantity/2 AS quantity)
080     *
081     * @return replace expr as identifier list
082     */
083    public ArrayList<TReplaceExprAsIdentifier> getExprAsIdentifiers() {
084        return exprAsIdentifiers;
085    }
086
087    /**
088     * Bigquery except columns
089     * SELECT COMMON.* EXCEPT (column1, column2) FROM dataset1.table1 COMMON;
090     *
091     * @return Bigquery except columns
092     */
093    public TObjectNameList getExceptColumnList() {
094        return exceptColumnList;
095    }
096
097    private TObjectNameList exceptColumnList;
098
099    /**
100     * BigQuery select * except(expr as identifier)
101     * @return
102     */
103    public ArrayList<TReplaceExprAsIdentifier> getReplaceExprAsIdentifiers() {
104        return replaceExprAsIdentifiers;
105    }
106
107    private  ArrayList<TReplaceExprAsIdentifier>  replaceExprAsIdentifiers;
108
109    private TQualifyClause qualifyClause;
110
111    public void setQualifyClause(TQualifyClause qualifyClause) {
112        this.qualifyClause = qualifyClause;
113    }
114
115    public TQualifyClause getQualifyClause() {
116
117        return qualifyClause;
118    }
119
120    public void setDataTypeConversionList(TPTNodeList<TExplicitDataTypeConversion> dataTypeConversionList) {
121        expr.setDataTypeConversionList(dataTypeConversionList);
122    }
123
124    private  TPTNodeList <TExplicitDataTypeConversion> dataTypeConversionList = null; // teradata
125
126    private TObjectNameList targetColumns = null;
127
128    public TObjectNameList getTargetColumns() {
129        if (targetColumns == null) targetColumns = new TObjectNameList();
130        return targetColumns;
131    }
132
133    public boolean isMatchedUsingAlias(TObjectName pColumn){
134        boolean lcResult = pColumn.getColumnNameOnly().equalsIgnoreCase(getColumnAlias());
135        return lcResult;
136    }
137
138    public boolean isMatchedWithResultColumn(EDbVendor dbVendor, TObjectName pColumn){
139       // boolean lcResult = pColumn.getColumnNameOnly().equalsIgnoreCase(getColumnAlias());
140        //boolean lcResult = TSQLObject.compareTo(dbVendor, ESQLDataObjectType.dotColumn,pColumn.getColumnNameOnly(),getColumnAlias()) == 0;
141        boolean lcResult = TSQLEnv.compareIdentifier(dbVendor, dotColumn,pColumn.getColumnNameOnly(),getColumnAlias());
142        if ((getColumnAlias().length() > 0) && (!lcResult)){
143            return lcResult;
144        }
145        if (! lcResult) {
146            //lcResult = pColumn.getColumnNameOnly().equalsIgnoreCase(getColumnNameOnly());
147            //lcResult = TSQLObject.compareTo(dbVendor, ESQLDataObjectType.dotColumn,pColumn.getColumnNameOnly(),getColumnNameOnly()) == 0;
148            lcResult = TSQLEnv.compareIdentifier(dbVendor, dotColumn,pColumn.getColumnNameOnly(),getColumnNameOnly());
149        }
150
151        return lcResult;
152    }
153
154    public void TResultColumn(){
155
156    }
157
158    /**
159     * This is the display name shown in the output of select list
160     * @return display name
161     */
162    public String getDisplayName(){
163        if (getAliasClause() != null) return  getAliasClause().toString();
164        String result = "";
165        switch (expr.getExpressionType()){
166            case sqlserver_proprietary_column_alias_t:
167                if (expr.getRightOperand().getExpressionType() == EExpressionType.simple_object_name_t){
168                    result = expr.getRightOperand().getObjectOperand().getColumnNameOnly();
169                }
170                break;
171            case simple_object_name_t:
172                result = expr.getObjectOperand().getColumnNameOnly();
173                break;
174            default:
175                result = toString();
176                break;
177        }
178        return result;
179    }
180
181    public String getColumnAlias(){
182        if (getAliasClause() != null) return  getAliasClause().toString();
183        else return "";
184    }
185
186    public TObjectName getColumnFullname(){
187        TObjectName result = null;
188        switch (expr.getExpressionType()){
189            case sqlserver_proprietary_column_alias_t:
190                if (expr.getRightOperand().getExpressionType() == EExpressionType.simple_object_name_t){
191                    result = expr.getRightOperand().getObjectOperand();
192                }
193                break;
194            case simple_object_name_t:
195                result = expr.getObjectOperand();
196                break;
197            default:
198                break;
199        }
200        return result;
201    }
202
203    public String getColumnNameOnly(){
204        String result = "";
205        switch (expr.getExpressionType()){
206            case sqlserver_proprietary_column_alias_t:
207                if (expr.getRightOperand().getExpressionType() == EExpressionType.simple_object_name_t){
208                    result = expr.getRightOperand().getObjectOperand().getColumnNameOnly();
209                }
210                break;
211            case simple_object_name_t:
212                result = expr.getObjectOperand().getColumnNameOnly();
213                break;
214            case typecast_t:
215                result = expr.getLeftOperand().toString();
216                break;
217            default:
218                break;
219        }
220//        if (expr.getExpressionType() == EExpressionType.simple_object_name_t) return expr.getObjectOperand().getColumnNameOnly();
221//        else return "";
222
223        return result;
224    }
225
226    private TExpression expr = null;
227
228    public void setExpr(TExpression expr) {
229        this.expr = expr;
230    }
231
232    private  boolean placeHolder = false;
233
234    public void setPlaceHolder(boolean placeHolder) {
235        this.placeHolder = placeHolder;
236    }
237
238    /**
239     * this is true when  there is no column names specified for fields in teradata insert statement
240     * <p>
241     * INSERT INTO employee (10005, 'Orebo B',300,,,, 'Nov 17 1957','M',,,18,);
242     * @return
243     */
244    public boolean isPlaceHolder(){
245        return this.placeHolder;
246    }
247    /**
248     * column expression.
249     * If there is only column name in a select_list item, then, this expr is type of {@link TExpression#simpleObjectname},
250     * <p>Otherwise, it maybe a complex expr, you should check {@link TExpression#getExpressionType}.
251     * <p>for column values in update_set_clause, this expr is type of {@link TExpression#ASSIGNMENT}
252     * @return
253     */
254    public TExpression getExpr() {
255        return expr;
256    }
257
258
259    public void init(Object arg1)
260    {
261        if (arg1 instanceof TExpression){
262            expr = (TExpression)arg1;
263        }
264    }
265
266    public void init(Object arg1, Object arg2)
267    {
268        init(arg1);
269        if (arg2 instanceof TAliasClause) {
270            this.setAliasClause((TAliasClause) arg2);
271            if (((TAliasClause) arg2).getAliasName() != null) {
272                ((TAliasClause) arg2).getAliasName().setObjectType(TObjectName.ttobjColumnAlias);
273            }
274        }
275    }
276
277
278    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
279        if (this.isPlaceHolder()) return ;
280
281        if(psql.dbvendor == EDbVendor.dbvteradata){
282            boolean foundNamedDataAttribute = false;
283            if (expr.getDataConversions().size() > 0 ){
284                for(int i=0;i<expr.getDataConversions().size();i++){
285                    TDataConversion dataConversion = expr.getDataConversions().get(i);
286                    for(int j=0;j<dataConversion.getDataConversionItems().size();j++){
287                        TDataConversionItem dataConversionItem = dataConversion.getDataConversionItems().get(j);
288                        if (dataConversionItem.getDataConversionType() == TDataConversionItem.EDataConversionype.dataAttribute){
289                            TDatatypeAttribute datatypeAttribute = dataConversionItem.getDatatypeAttribute();
290                            if (datatypeAttribute.getAttributeType() == EDataTypeAttribute.named_t){
291                                TAliasClause aliasClause = new TAliasClause();
292
293                                aliasClause.init(datatypeAttribute.getNamedName());
294                                aliasClause.setStartToken(datatypeAttribute.getNamedName());
295                                aliasClause.setEndToken(datatypeAttribute.getNamedName());
296
297                                aliasClause.setTeradataNamedAlais(true);
298                                aliasClause.setAsToken(datatypeAttribute.getStartToken());
299                                this.setAliasClause(aliasClause);
300
301                                foundNamedDataAttribute = true;
302                                break;
303                            }
304                        }
305                    }
306                    if (foundNamedDataAttribute) break;
307                }
308            }
309
310//            if (expr.getDataTypeConversionList() != null){
311//                boolean namedAlias = false;
312//                TDatatypeAttribute datatypeAttribute = null;
313//                for(int i=0;i<expr.getDataTypeConversionList().size();i++){
314//                    TExplicitDataTypeConversion e = expr.getDataTypeConversionList().getElement(i);
315//                    if (e.getDataTypeAttributeList1() == null) continue;
316//                    for(int j=0;j<e.getDataTypeAttributeList1().size();j++){
317//                        datatypeAttribute = e.getDataTypeAttributeList1().getElement(j);
318//                        if (datatypeAttribute.getAttributeType() == EDataTypeAttribute.named_t){
319//                            break;
320//                        }else {
321//                            datatypeAttribute = null;
322//                        }
323//                    }
324//                    if (datatypeAttribute != null) break;
325//                }
326//
327//                if (datatypeAttribute != null){
328//                    if (datatypeAttribute.getAttributeType() == EDataTypeAttribute.named_t){
329//                        TAliasClause aliasClause = new TAliasClause();
330//                        if (datatypeAttribute.getValue_literal() != null){
331//                            aliasClause.init(datatypeAttribute.getValue_literal());
332//                            aliasClause.setStartToken(datatypeAttribute.getValue_literal().getStartToken());
333//                            aliasClause.setEndToken(datatypeAttribute.getValue_literal().getEndToken());
334//                        }else if (datatypeAttribute.getValue_identifier() != null){
335//                            aliasClause.init(datatypeAttribute.getValue_identifier());
336//                            aliasClause.setStartToken(datatypeAttribute.getValue_identifier());
337//                            aliasClause.setEndToken(datatypeAttribute.getValue_identifier());
338//                        }
339//                        aliasClause.setTeradataNamedAlais(true);
340//                        aliasClause.setAsToken(datatypeAttribute.getStartToken());
341//                        this.setAliasClause(aliasClause);
342//                        namedAlias = true;
343//                    }
344//                }
345//
346//                if(!namedAlias){
347//                    //expr.setEndToken(expr.getDataTypeConversion().getEndToken());
348//                }
349//
350//                //this.setEndToken(expr.getEndToken());
351//            }
352
353            // select col1 (DATE) from tab1
354//            if (expr.getExpressionType() == EExpressionType.function_t){
355//                TFunctionCall f = expr.getFunctionCall();
356//                if ((f.getArgs() != null)&&(f.getArgs().size() == 1)){
357//                    if (f.getArgs().getExpression(0).toString().equalsIgnoreCase("date")){
358//                        expr.setExpressionType(EExpressionType.simple_object_name_t);
359//                        f.getFunctionName().setDbObjectType(EDbObjectType.column);
360//                        f.getFunctionName().setPartToken(f.getFunctionName().getObjectToken());
361//                        f.getFunctionName().setObjectToken(null);
362//                        expr.setObjectOperand(f.getFunctionName());
363//                        expr.setStartToken(f.getFunctionName().getStartToken());
364//                        expr.setEndToken(f.getFunctionName().getEndToken());
365//                        //
366//                        TTypeName date1 = new TTypeName();
367//                        date1.init(EDataType.date_t.date_t);
368//                        date1.setStartToken(f.getArgs().getExpression(0).getStartToken());
369//                        date1.setEndToken(f.getArgs().getExpression(0).getEndToken());
370//                        TExplicitDataTypeConversion dtc = new TExplicitDataTypeConversion();
371//                        dtc.init(date1);
372//                        dtc.setStartToken(date1.getStartToken());
373//                        dtc.setEndToken(date1.getEndToken());
374//
375//                        TPTNodeList<TExplicitDataTypeConversion> dtcList = new TPTNodeList<TExplicitDataTypeConversion>();
376//                        dtcList.addNode(dtc);
377//                        expr.setDataTypeConversionList(dtcList);
378//                    }
379//                }
380//            }
381
382        }
383        // change plocation when resultcolumn is in update or insert
384        if (plocation == ESqlClause.set){
385            if (expr.getExpressionType() == EExpressionType.function_t){
386                /*
387                 *   UPDATE Cities
388                 *   SET Location.SetXY(23.5, 23.5)
389                 */
390                //expr.getFunctionCall().getFunctionName().parseColumnMethodName();
391                try{
392                    expr.getFunctionCall().getFunctionName().setObjectType(TObjectName.ttobjColumnMethod);
393                   // expr.getFunctionCall().getFunctionName().setDbObjectType(EDbObjectType.method);
394                }catch (Exception e){
395                    TSourceToken st = expr.getStartToken();
396                    psql.parseerrormessagehandle(new TSyntaxError(st.astext, st.lineNo, st.columnNo
397                            ,"error function call in set clause", EErrorType.spfatalerror
398                            , TBaseType.MSG_ERROR_FUNCTION_IN_SET_CLAUSE
399                            ,psql,st.posinlist));
400                }
401                if( (expr.getFunctionCall().getFunctionName().getPartToken()!=null)&&(psql.getTargetTable()!=null)){
402                    TObjectName columName = TObjectName.createObjectName (psql.dbvendor, EDbObjectType.column,expr.getFunctionCall().getFunctionName().getPartToken());
403                    psql.getTargetTable().getLinkedColumns().addObjectName (columName);
404                    columName.setSourceTable(psql.getTargetTable());
405                    columName.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM);
406                }else{
407                     psql.linkColumnToTable(expr.getFunctionCall().getFunctionName(),plocation);
408                }
409
410                if (expr.getFunctionCall().getArgs() != null){
411                    for(int i=0;i<expr.getFunctionCall().getArgs().size();i++){
412                        expr.getFunctionCall().getArgs().doParse(psql,plocation);
413                    }
414                }
415              //  psql.linkColumnReferenceToTable( TGSqlParser.parseObjectName(psql.dbvendor, expr.getFunctionCall().getFunctionName().getPartToken().astext) ,plocation);
416            }else {
417                 if (expr.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t){
418                     expr.getLeftOperand().getObjectOperand().setLocation(plocation);
419                     TTable lcTable = psql.tables.getTable(0);
420                     if (lcTable.isLinkTable()) lcTable = lcTable.getLinkTable();
421                     lcTable.getLinkedColumns().addObjectName(expr.getLeftOperand().getObjectOperand());
422                     expr.getLeftOperand().getObjectOperand().setSourceTable(lcTable);
423                     expr.getLeftOperand().getObjectOperand().setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM);
424                     lcTable.getObjectNameReferences().addObjectName(expr.getLeftOperand().getObjectOperand());
425                     expr.getRightOperand().doParse(psql,ESqlClause.setValue);
426                 }else {
427                     expr.doParse(psql,plocation);
428                 }
429            }
430            //psql.linkColumnToTable()
431        }else if (
432                (expr.getExpressionType() == EExpressionType.simple_comparison_t)
433                &&((psql.dbvendor == EDbVendor.dbvmssql)||(psql.dbvendor == EDbVendor.dbvsybase))
434                &&(
435                        (plocation == ESqlClause.resultColumn)
436                        ||(plocation == ESqlClause.insertColumn)
437                                ||(plocation == ESqlClause.mergeInsert)
438                                ||(plocation == ESqlClause.selectList)
439                )
440
441            )
442        {
443            //@x in  select @x = id is not a alias
444            if (
445                (expr.getComparisonOperator().toString().equalsIgnoreCase("="))
446                 &&(!(expr.getLeftOperand().toString().startsWith("@")))
447                  ){
448                //expr.setExpressionType(TExpression.sqlserver_proprietary_column_alias);
449                expr.setExpressionType(EExpressionType.sqlserver_proprietary_column_alias_t);
450                TAliasClause aliasClause  = new TAliasClause();
451                if (expr.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t){
452                    aliasClause.init(expr.getLeftOperand().getObjectOperand());
453                    aliasClause.setStartToken(expr.getLeftOperand().getStartToken());
454                    aliasClause.setEndToken(expr.getLeftOperand().getEndToken());
455                }else if (expr.getLeftOperand().getExpressionType() == EExpressionType.simple_constant_t){
456                    aliasClause.init(expr.getLeftOperand().getConstantOperand());
457                    aliasClause.setStartToken(expr.getLeftOperand().getStartToken());
458                    aliasClause.setEndToken(expr.getLeftOperand().getEndToken());
459                }
460                setAliasClause(aliasClause);
461            }
462            expr.doParse(psql,plocation);
463        }else if((psql.dbvendor == EDbVendor.dbvpostgresql)
464                &&(expr.getExpressionType() == EExpressionType.simple_constant_t)
465                &&(plocation == ESqlClause.selectList)
466                &&(expr.getObjectOperand() != null)&&(expr.getExprAlias() != null)
467        ){// func_name Sconst /* generic type 'literal' syntax */
468            expr.setExpressionType(EExpressionType.simple_object_name_t);
469            setAliasClause(expr.getExprAlias());
470            getAliasClause().setStartToken(expr.getExprAlias().getStartToken());
471            getAliasClause().setEndToken(expr.getExprAlias().getEndToken());
472            expr.doParse(psql,plocation);
473        }else{
474            expr.doParse(psql,plocation);
475        }
476
477        if (qualifyClause != null){
478            qualifyClause.doParse(psql,plocation);
479        }
480
481//        if ((expr.getFieldList() != null) && (psql.dbvendor == EDbVendor.dbvbigquery)){
482//            // SELECT COMMON.* EXCEPT (column1, column2) FROM dataset1.table1 COMMON;
483//            this.exceptColumnList = expr.getFieldList();
484//            TTable table = psql.tables.getTable(0);
485//            if (table != null){
486//                for(int i=0;i<this.exceptColumnList.size();i++){
487//                    table.getLinkedColumns().addObjectName(this.exceptColumnList.getObjectName(i));
488//                    this.exceptColumnList.getObjectName(i).setSourceTable(table);
489//                }
490//            }
491//        }
492
493        if (expr.getExceptReplaceClause() != null){
494            // SELECT COMMON.* EXCEPT (column1, column2) FROM dataset1.table1 COMMON;
495            this.exceptColumnList = expr.getExceptReplaceClause().getColumnList();
496
497            // select * replace(expr as identifier)
498            this.replaceExprAsIdentifiers = expr.getExceptReplaceClause().getExprAsIdentifiers();
499
500            TTable table = psql.tables.getTable(0);
501            if (table != null){
502                if (this.exceptColumnList != null){
503                    for(int i=0;i<this.exceptColumnList.size();i++){
504                        table.getLinkedColumns().addObjectName(this.exceptColumnList.getObjectName(i));
505                        this.exceptColumnList.getObjectName(i).setSourceTable(table);
506                    }
507                }
508
509                if (replaceExprAsIdentifiers != null){
510                    for(int i=0;i<replaceExprAsIdentifiers.size();i++){
511                        TReplaceExprAsIdentifier replaceExprAsIdentifier = replaceExprAsIdentifiers.get(i);
512                        table.getLinkedColumns().addObjectName(replaceExprAsIdentifier.getIdentifier());
513                        replaceExprAsIdentifier.getIdentifier().setSourceTable(table);
514                    }
515                }
516            }
517
518        }
519    }
520
521
522    /**
523     *
524     * @return this is used to provide back compatibility of .NET version only. 
525     */
526    public TObjectName getFieldAttr() {
527        TObjectName ret = null;
528        if (expr.getExpressionType() == EExpressionType.simple_object_name_t){
529            ret = expr.getObjectOperand();
530        }
531        return ret;
532    }
533
534    public String getPrefixTable(){
535        if (getFieldAttr() == null) return "";
536        return getFieldAttr().getTableString();
537    }
538
539    public String getPrefixSchema(){
540        if (getFieldAttr() == null) return "";
541        return getFieldAttr().getSchemaString();
542    }
543
544    public String getPrefixDatabase(){
545        if (getFieldAttr() == null) return "";
546        return getFieldAttr().getDatabaseString();
547    }
548
549    public String getPrefixServer(){
550        if (getFieldAttr() == null) return "";
551        return getFieldAttr().getServerString();
552    }
553
554    public void accept(TParseTreeVisitor v){
555        v.preVisit(this);
556        v.postVisit(this);
557    }
558
559    public void acceptChildren(TParseTreeVisitor v){
560        v.preVisit(this);
561
562        if (!placeHolder)  getExpr().acceptChildren(v);
563        if (getAliasClause() != null){
564            getAliasClause().acceptChildren(v);
565        }
566
567        v.postVisit(this);
568    }
569
570    public void setTargetColumns(TObjectNameList targetColumns) {
571        this.targetColumns = targetColumns;
572    }
573
574    private TUpdateFor updateFor; //couchbase
575
576    public void setUpdateFor(TUpdateFor updateFor) {
577        this.updateFor = updateFor;
578    }
579
580    public TUpdateFor getUpdateFor() {
581
582        return updateFor;
583    }
584
585    public int compareTo(Object o){
586        TResultColumn rc = (TResultColumn)o;
587        return  TSQLEnv.normalizeIdentifier(this.dbvendor,dotColumn, this.getDisplayName()).compareTo(
588                TSQLEnv.normalizeIdentifier(this.dbvendor,dotColumn,rc.getDisplayName())) ;
589
590    }
591
592//    private int pos = -1;
593//
594//    public void setPos(int pos) {
595//        this.pos = pos;
596//    }
597//
598//    public int getPos() {
599//        return pos;
600//    }
601}