QBE problem solved ? (long-ish)
Posted in 1992
Topics: Connectivity: ESQL/C, 4GL & Embedded SQL
I recently asked for help on the QBE "<>?/??/???" problem; I have now written some 4gl code which I can insert where my constructs are. (no 4gl function, no C function, since stupid 512 byte stack limit :-<) It requires certain variables to be declared and to know the name of the 'input' and 'output' construct strings, but no knowledge of the tables/columns is required. taking a construct string like this (indented for ease of reading) test.ts_col1 matches "A?B*|<>FRED*" and test.ts_col2 between "1" and "2" and test.ts_col3 matches "A*|<>B*|<>C*|D*" and test.ts_col4>"1.67" my code converts it into this (indented for ease of reading) (test.ts_col1 matches "A?B*" or test.ts_col1 not matches "FRED*") and (test.ts_col2 between "1" and "2") and (test.ts_col3 matches "A*" or test.ts_col3 not matches "B*" or test.ts_col3 not matches "C*" or test.ts_col3 matches "D*") and (test.ts_col4>"1.67") My code currently ignores ranges since ranges in wild card strings is senseless. It also introduces its own problems in that it is now not possible to use the expression <>* to mean the literal '*' (if only != and <> would evaluate to != and <> instead of both to <> :-<) the code that follows will require altering to suit your construct environment. no gaurantees can be given since I only recently did this and have only run it on test programs so far. ------------------------------- DEFINITIONS ------------------------------------ define in_constr char(1024) {names/sizes examples only} define out_constr char(1024) define i integer define j integer define k integer define l integer define m integer define n integer define between_flag integer --------------------------- END DEFINITIONS ------------------------------------ following your construct ------------------------------- 4GL CODE --------------------------------------- let i = 1 let out_constr[1,1]="(" let j = 2 let k = 1 let between_flag = FALSE while i <= length(in_constr) case when in_constr[i,i+8]=" between " let between_flag = TRUE let out_constr[j,j+8] = in_constr[i,i+8] let i = i + 9 let j = j + 9 when in_constr[i,i+3]=" or " let out_constr[j,j+5]=") or (" let i = i + 4 let j = j + 6 when in_constr[i,i+4]=" and " if between_flag then let out_constr[j,j+4]=in_constr[i,i+4] let j = j + 5 let between_flag = FALSE else let out_constr[j,j+6]=") and (" let j = j + 7 end if let i = i + 5 when in_constr[i,i+2]='<>"' let n = i-256 {this code finds} if n < 1 {the previous} then {occurence of} let n = 1 {table.column} end if {in the 'input'} let m = rfind_str(in_constr[n,i-1]," ") {construct string} let m = n + m let n = i - m - 1 {ie in_constr[m,n]} let k = find_str(in_constr[i+3,i+258],'" {now find any} if find_str(in_constr[i+3,i+k+2],'?') {wild cards} or find_str(in_constr[i+3,i+k+2],'*') or find_str(in_constr[i+3,i+k+2],'|') then let out_constr[j,j+13]=' not matches "' {sub for <>} let j = j + 14 let i = i + 3 let k = find_str(in_constr[i,i+255],'"'){end of match bit} let l = find_str(in_constr[i,i+k-1],'|'){any | or's present} while l > 0 let out_constr[j,j+l-2] = in_constr[i,i+l-2] if in_constr[i+l,i+l+1]='<>' {uses |<>} then let out_constr[j+l-1,j+l+n+18] = '" or ', in_constr[m,m+n], ' not matches "' let j = j + l + n + 19 let i = i + l + 2 let k = k - l - 2 else {or |} let out_constr[j+l-1,j+l+n+14] = '" or ', in_constr[m,m+n], ' matches "' let j = j + l + n + 15 let i = i + l let k = k - l end if let l = find_str(in_constr[i,i+k-1],'|') end while end if when in_constr[i,i+9]=' matches "' let n = i-256 if n < 1 then let n = 1 end if let m = rfind_str(in_constr[n,i-1]," ") let m = n + m let n = i - m -1 let out_constr[j,j+9]=in_constr[i,i+9] let i = i + 10 let j = j + 10 let k = find_str(in_constr[i,i+255],'"') let l = find_str(in_constr[i,i+k-1],'|') while l > 0 let out_constr[j,j+l-2] = in_constr[i,i+l-2] if in_constr[i+l,i+l+1]='<>' then let out_constr[j+l-1,j+l+n+18] = '" or ', in_constr[m,m+n], ' not matches "' let j = j + l + n + 19 let i = i + l + 2 let k = k - l - 2 else let out_constr[j+l-1,j+l+n+14] = '" or ', in_constr[m,m+n], ' matches "' let j = j + l + n + 15 let i = i + l let k = k - l end if let l = find_str(in_constr[i,i+k-1],'|') end while otherwise let out_constr[j,j]=in_constr[i,i] let i = i + 1 let j = j + 1 end case end while let out_constr[j,j]=")" ----------------------------- END 4GL CODE ------------------------------------- following are 4GL inplementations of rfind_str and find_str -------------------------------------------------------------------------------- function rfind_str(l_string,l_seek) define l_string char(512) d