bool r_srt_set() { /* internal declarations */ register SORT *srt; /* fast ptr to SORT array */ i4 sequence; /* sort sequence number */ ATTRIB ordinal; /* attribute ordinal */ bool noerr = TRUE; /* abort if error in sort vars */ /* start of routine */ En_n_sorted = En_scount; if (En_n_sorted < 1) { /* no sort attributes specified */ En_n_sorted = 0; return(noerr); } /* no sort attributes specified */ /* go through the database lines and convert */ for(sequence=1,srt=Ptr_sort_top; sequence<=En_n_sorted; srt++,sequence++) { CVlower(srt->sort_break); CVlower(srt->sort_direct); if ((ordinal=r_mtch_att(srt->sort_attid)) < 0) { /* attribute not in data relation */ r_error(0x06, NONFATAL, srt->sort_attid, NULL); noerr = FALSE; continue; } /* attribute not in data relation */ srt->sort_ordinal = ordinal; } if (!noerr) { En_n_sorted = 0; return(noerr); } return(noerr); }
bool rFqur_set() { /* internal declarations */ i4 sequence; /* current seq in QUR array */ register QUR *qur; /* fast ptr to QUR array */ i4 rfq_parse_state; /* ** Scanning state for where ** clause. */ i4 type; /* Token type returned */ bool rfq_error; /* TRUE if parse error occurs*/ i4 ord; /* ordinal of attribute */ COPT *copt; /* Copt structure */ char *qual; /* Pointer to qualification */ char *n_qual; /* ** Pointer to qualification ** after skip to any parens ** for JoinDef */ char chk_char; /* ** Hold current char to check ** for comments. */ char rvar[FE_UNRML_MAXNAME+1]; /* Range Var name in where */ char attname[FE_UNRML_MAXNAME+1]; /* Attribute name in where */ char ColName[FE_MAXNAME+1]; /* RBF Internal column name */ FE_RSLV_NAME rfq_ferslv; /* ** Work struct to decompose ** compound identifiers. */ /* start of routine */ # ifdef xRTR1 if (TRgettrace(200,0)) { SIprintf(ERx("rFqur_set: entry.\r\n")); } # endif qual = NULL; for (sequence = 1,qur = Ptr_qur_arr; sequence <= En_qcount; qur++,sequence++) { CVlower(qur->qur_section); if (STcompare(qur->qur_section,NAM_WHERE) == 0) { _VOID_ rfNextQueryLine(&qual, qur->qur_text); } } /* ** If we are here when creating a new report, we don't have ** any selection criteria to look for. */ if (qual == NULL) { return(TRUE); } if (*qual == EOS) { _VOID_ MEfree((PTR)qual); return(TRUE); } /* ** If the source of data is a JoinDef, we need to skip over ** the part of the qualification that defines the join. So, find ** any open parenthesis - if none, then no selection criteria exist. ** Otherwise, reset the qual pointer to the open parens. */ n_qual = qual; if ((En_SrcTyp == JDRepSrc) && ((n_qual = STindex(qual,ERx("("),0)) == NULL)) { return(TRUE); } r_g_set(n_qual); rfq_error = FALSE; rfq_parse_state = FIND_OPAREN; /* ** Note that the parse state won't change until we first see ** an open parens. */ while ((!rfq_error) && ((type = r_g_skip()) != TK_ENDSTRING)) { switch(type) { case(TK_ALPHA): case(TK_QUOTE): if (type == TK_QUOTE) { /* ** Check for QUEL string constant first, ** then check for disallowed delimited ** identifier. */ if (En_qlang == FEDMLQUEL) { _VOID_ MEfree((PTR)r_g_string( TK_QUOTE)); break; } else if (!Rbf_xns_given) { rfq_error = TRUE; break; } } rfq_ferslv.name = r_g_ident(TRUE); /* ** Handle the relation operator 'LIKE' if ** that's what we're looking for. Note that ** for it to be a valid identifier, it would have ** to be in quotes! */ if ((rfq_parse_state == FIND_GREATER) && (STbcompare(rfq_ferslv.name, STlength(rfq_ferslv.name), ERx("like"), STlength(ERx("like")),TRUE) == 0)) { rfq_parse_state = FIND_OPAREN; _VOID_ MEfree((PTR)rfq_ferslv.name); break; } /* ** Handle the start of the UNION SELECT clause - ** it means that we're all done. However, unless the ** state is FIND_OPAREN, then we have an error which ** the subsequent identifier check will catch (failed ** for the identifier being a reserved word). Note ** that for it to be a valid identifier, it would have ** to be in quotes! */ if ((rfq_parse_state == FIND_OPAREN) && (STbcompare(rfq_ferslv.name, STlength(rfq_ferslv.name), ERx("union"), STlength(ERx("union")),TRUE) == 0)) { _VOID_ MEfree((PTR)rfq_ferslv.name); _VOID_ MEfree((PTR)qual); return(TRUE); } /* ** Keep skipping unless we're looking for an ** identifier. This will handle LOGICALS like ** AND, OR, etc., as well as right side expressions. */ if (rfq_parse_state != FIND_IDENT) { _VOID_ MEfree((PTR)rfq_ferslv.name); break; } rfq_ferslv.name_dest = &attname[0]; rfq_ferslv.owner_dest = &rvar[0]; rfq_ferslv.is_nrml = FALSE; FE_decompose(&rfq_ferslv); if ((IIUGdlm_ChkdlmBEobject(rfq_ferslv.name_dest, rfq_ferslv.name_dest, rfq_ferslv.is_nrml) == UI_BOGUS_ID) || ((rfq_ferslv.owner_spec) && (IIUGdlm_ChkdlmBEobject(rfq_ferslv.owner_dest, rfq_ferslv.owner_dest, rfq_ferslv.is_nrml) == UI_BOGUS_ID))) { rfq_error = TRUE; _VOID_ MEfree((PTR)rfq_ferslv.name); break; } if (En_SrcTyp == JDRepSrc) { if (!r_JDMaintAttrList(JD_ATT_GET_ATTR_NAME, &rvar[0],&attname[0], &ColName[0])) { /* ** Why doesn't this result in the fatal error ** that a parse failure would? The 6.4 version ** would actually fail here if a UNION SELECT ** was present and return - rFdisplay() does ** not check the return code. Since we now ** handle the end of the WHERE clause in a more ** sane manner, maybe this should be a fatal ** error ... */ _VOID_ MEfree((PTR)rfq_ferslv.name); _VOID_ MEfree((PTR)qual); return(FALSE); } STcopy(&ColName[0],&attname[0]); } ord = r_mtch_att(&attname[0]); if (ord < 0) { /* Bad attribute name */ IIUGerr(E_RF003A_rFqur_set__Bad_attrib, UG_ERR_FATAL,1,&attname[0]); } /* ** Set the column options of the attribute. We assume ** its a value until/unless we find a range indicator. */ copt = rFgt_copt(ord); copt->copt_select = 'v'; rfq_parse_state = FIND_GREATER; _VOID_ MEfree((PTR)rfq_ferslv.name); break; case(TK_OPAREN): CMnext(Tokchar); /* Skip the paren */ if (rfq_parse_state == FIND_OPAREN) { rfq_parse_state = FIND_IDENT; break; } /* ** Ignore open parens unless we're specifically ** looking for them. This handles instances of ** min(), max(), etc. */ break; case(TK_CPAREN): CMnext(Tokchar); /* Skip the paren */ if ((rfq_parse_state == FIND_CPAREN) && (copt != (COPT *)NULL) && (copt->copt_select == 'r')) { rfq_parse_state = FIND_2CPAREN; copt = (COPT *)NULL; break; } if (rfq_parse_state == FIND_2CPAREN) { rfq_parse_state = FIND_OPAREN; break; } /* ** Ignore closing parens unless we're specifically ** looking for them. This also handles instances of ** min(), max(), etc. */ break; case(TK_EQUALS): case(TK_RELOP): CMnext(Tokchar); /* Skip the relation operator */ /* ** Handle '!=', '>=', '<=' compound operators */ if (*Tokchar == '=') { CMnext(Tokchar); } if (rfq_parse_state == FIND_GREATER) { if (type == TK_RELOP) { /* Must be a range of values */ copt->copt_select = 'r'; rfq_parse_state = FIND_CPAREN; } else { rfq_parse_state = FIND_OPAREN; } } break; case(TK_SQUOTE): CMnext(Tokchar); /* ** Handle single quoted string values atomically so ** we don't get confused by their containing parens, ** etc. */ _VOID_ MEfree((PTR)r_g_string(TK_SQUOTE)); break; case(TK_DOLLAR): CMnext(Tokchar); /* ** Handle variables independently from identifiers so ** we don't get confused by something like '$like'. ** Additionally, allow compound constructs so we don't ** get confused by something like "$abc.columnname". ** Note that this compound construct should only result ** from user modifications, and is detrimental only ** when the state is FIND_IDENT - we won't assign any ** ColumnOptions to columnname. */ _VOID_ MEfree((PTR)r_g_ident(TRUE)); break; default: /* ** We should only really be here if we see the start ** of a comment ... */ chk_char = *Tokchar; CMnext(Tokchar); if ((chk_char == '/') && (*Tokchar == '*')) { /* ** Note the implication that a comment may not ** "interrupt" the WHERE clause. If we ** allowed one to, then we'd have to add ** comment recognition to the entire parse ** loop to avoid being confused! */ _VOID_ MEfree((PTR)qual); return(TRUE); } break; } } if ((rfq_error) || (rfq_parse_state != FIND_OPAREN)) { IIUGerr(E_RF003B_rFqur_set__Bad_where_,UG_ERR_FATAL,0); } _VOID_ MEfree((PTR)qual); return(TRUE); }
rFcsreset() { /* internal declarations */ CS *cs; /* ptr to CS for att */ register LIST *list; /* fast ptr to list element */ register i4 i; /* counter */ FIELD *f; /* pointer to field */ CS *ntop; /* new Cs_top value */ CS *ncs; /* new CS ptr */ ATTRIB ordinal; /* ordinal of this attribute */ bool associated; /* associated to column */ /* start of routine */ # ifdef xRTR1 if (TRgettrace(180,0) || TRgettrace(181,0)) { SIprintf(ERx("rFcsreset: entry.\r\n")); } # endif ntop = (CS *) MEreqmem(0,(u_i4) En_n_attribs*sizeof(CS), TRUE,(STATUS *) NULL); /* first reorder the attributes into the ntop arrary */ for (i=1; i<=Cs_length; i++) { cs = rFgt_cs(i); # ifdef xRTR1 if (TRgettrace(181,0)) { SIprintf(ERx(" Next CS ord from VIFRED: %d\r\n"),i); rFpr_cs(cs); } # endif associated = FALSE; for (list=cs->cs_flist; list!=NULL; list=list->lt_next) { /* identify the attribute */ if ((f=list->lt_field) == NULL) { continue; } ordinal = r_mtch_att(f->fldname); if ((ordinal>0) && (ordinal<=En_n_attribs)) { /* found the attribute. Store list in ntop */ # ifdef xRTR3 if (TRgettrace(181,0)) { SIprintf(ERx(" Match on ordinal:%d: %s\r\n"), ordinal, f->fldname); } # endif ncs = &(ntop[ordinal-1]); ncs->cs_flist = cs->cs_flist; ncs->cs_tlist = cs->cs_tlist; associated = TRUE; break; } } if (!associated) /* not associated. ERROR */ IIUGerr(E_RF0025_rFcsreset___CS_struct, UG_ERR_FATAL, 0); } Cs_top = ntop; # ifdef xRTR3 if (TRgettrace(181,0)) { SIprintf(ERx(" At end of rFcsreset. CS_TOP:%p.\r\n"),Cs_top); } # endif return; }