BookmarkSubscribeRSS Feed
GiovannaEdmonds
Calcite | Level 5

This bug exists in both 9.4 and 9.2. Below are two tests.

If you run the tests and search for "len=2" or "len=1" in the log, you will find the following three outputs. The last one comes from RSubmit and is wrong.

Test 1Test 2

len=2001

len=2001

len=2002

len=1003

len=1003

len=15

This bug corrupts code containing spaces. I found this bug because an extra space is inserted into a column name, causing an SQL query to fail.

Test 1Test 2

%let k=1000;

%macro foo;
data _null_;
len = length("%sysfunc(repeat(x%bquote( ),&k.))");
put len=;
run;
%mend;

options noquotelenmax;

%foo;

data _null_;
call execute('%foo');
run;

data _null_;
call execute('signon t sascmd="!sascmdv";');
call execute('rsubmit t;');
call execute('options noquotelenmax;');
call execute('%foo');
call execute('endrsubmit;');
call execute('signoff t;');
run;

%let k=1000;

%macro foo;
data _null_;
len = length("x%sysfunc(repeat(%bquote( ),&k.))x");
put len=;
run;
%mend;

options noquotelenmax;

%foo;

data _null_;
call execute('%foo');
run;

data _null_;
call execute('signon t sascmd="!sascmdv";');
call execute('rsubmit t;');
call execute('options noquotelenmax;');
call execute('%foo');
call execute('endrsubmit;');
call execute('signoff t;');
run;

5 REPLIES 5
LinusH
Tourmaline | Level 20

So, have you reported this to SAS tech support?

Data never sleeps
FriedEgg
SAS Employee

This is not a bug, you have not programmed it correctly.  Why are you even using the call execute's?  That really only complicates things unnecessarily.

Rather than walking through how to fix this example.  If you care to share something closer to the situation you are actually dealing with (the SQL you mention...).  It would be easier to help, I feel.

GiovannaEdmonds
Calcite | Level 5

Thank you for your reply. There are good reasons for using call execute, and the workarounds for this bug make compromises on those reasons. Imagine that the macro is thousands of lines long, or is user-supplied at run time. And then imagine a choreography of several such macros with potentially hundreds of RSubmits (both sequential and parallel). The value of call execute is clear. The workaround to this bug involves %include or sasautos. The drawbacks of saving the macro externally are inconvenience to the user and not being to use the version control inside enterprise guide. Furthermore, the macro is stored on the server, instead of beig encapsulating within a single EG project file, which are often stored on separate filesystems.

FriedEgg
SAS Employee

You reasoning for using the CALL EXECUTE is to have you macro compile locally and transfer the generated SAS code/text to the remote server for execution.  I understand why you feel this should be treated as a bug, but, I also feel that your approach is mostly what is flawed.  As Linus said, the appropriate place to report bugs is with SAS Tech Support.

In your specific example, rewriting the FOO macro to something like the following resolves all your issues:

%macro foo;

data _null_;

foo = cat('x', repeat(' ', &k.), 'x');

len = length(foo);

put len=;

run;

%mend;


My recommendation would be to transfer the macro (even when compile in work on the client session) to the remote session and have it execute there.

%let k=1000;

%macro foo(session, k);

data _null_;

len = length("x%sysfunc(repeat(%bquote( ),&k.))x");

put ">>>&session. " len=;

run;

%mend;

/* transfer macro FOO to remote, for non-shared file systems using PROC UPLOAD could be used instead of inheritlib option, this is example for MP-CONNECT style rsubmit */

options dlcreatedir;

libname tmp "%sysfunc(pathname(work,l))/mstore";

proc catalog c=work.sasmacr et=macro;

copy out=tmp.sasmacr;

select foo;

run;

options noquotelenmax;

%foo(local, &k.)

signon t sascmd='!sascmd' inheritlib=(tmp);

%syslput k=&k.;

rsubmit t;

options noquotelenmax;

options mstored sasmstore=tmp;

%foo(remote, &k.);

endrsubmit;

signoff t;

data _null_;

call execute('signon t sascmd="!sascmd" inheritlib=(tmp);');

call execute('%nrstr(%syslput k=&k.;)');

call execute('rsubmit t;');

call execute('options noquotelenmax;');

call execute('options mstored sasmstore=tmp;');

call execute('%nrstr(%foo(remote, &k.);)');

call execute('endrsubmit;');

call execute('signoff t;');

run;

GiovannaEdmonds
Calcite | Level 5

Thank you for your reply. I am just posting here so people are aware of the bug. It's quite pernicious imo. call execute() is not a flawed approach. It is in fact the most elegant approach (if not for the bug described here). By elegant I mean it needs the fewest lines of code. The drawback with mstored is that “%syslput _user_;” is not available in 9.2, so more code is needed to hunt down all of the user’s macro variables. Imagine a dynamic environment where the users do whatever they want. (By "users" I really mean other programmers.) To give you a bit more background, my code is generated through a data step based on user input and a very complex logic. Each step, when generated, is inserted into a hash table (so they don't have to be generated in the same order as the actual execution). In the end of the data step, a hiter loop is used and call execute() is applied. As for %foo, I concocted it just to demonstrate the bug. I don't really need one thousand x's. If you have code that's written as state = "New York", the bug would have SAS run state = "New  York" instead (note the double spaces between New and York). No rewriting can avoid getting the wrong output in that case.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 1045 views
  • 0 likes
  • 3 in conversation