Match the Adobe CF behavior of treating query columns as arrays


#1

This has been discussed before, but I’ve never been pleased with the answer so I’d like it to be discussed again. Please provide any public feedback before the TAG addresses it.

https://luceeserver.atlassian.net/browse/LDEV-544

This is an Adobe ColdFusion incompatibility, but I’m entering this as an enhancement because it’s been discussed several times before and previously was stated that it was on purpose so I’d like to address the previous decision which the TAG can help do.
Adobe CF allows array functions to be against query columns like so:

myQry = queryNew( 'amount' );
myQry.addRow();
myQry.setCell( 'amount', 5, 1 );
myQry.addRow();
myQry.setCell( 'amount', 15, 2 );
writeOutput( arraySum( myQry[ 'amount' ] ) );

Adobe CF returns “20”, but Lucee throws the exception, "Can’t cast Object type Number to a value of type Array ".
Lucee provides a separate function called QueryColumnData() to get the data in a query column back as an array. I’d like to discuss providing compatibility with Adobe Cf for the following reasons:

  1. I think their syntax is succinct and makes sense
  2. This has been a stumbling block I’ve seen mentioned in just about every blog article I’ve ever read about converting to Railo/Lucee.
  3. I regularly hear people complaining about running into this and not understanding why their code doesn’t run. (just this week on Twitter)
  4. This has been a pain for every single Adobe CF app I have ever converted to Lucee myself
  5. I’m having to waste time right now, again, on this issue in an app I’m converting and i really just wish it worked.

I get that Lucee has a function for this and I think that’s great, but I want to see Lucee also allow for the shortcut syntax of address query columns as arrays for the pure sake of helping people convert their ACF code over to Lucee.

Discuss.

Ooh, and I’ll try out one of these poll doohickey’s @modius showed us

Should query columns be treated as an array like Adobe CF?

  • Yes, this is useful
  • No, that is not useful
  • I don’t care, when is Lucee 5 coming out??
  • What is Adobe ColdFusion?

0 voters


#2

just playing with this as I can’t see how it would work in ACF

This
dump(var=myQry[ ‘amount’ ]);
returns 5


#3

Adobe only treats it as an array if you try to use it as an array. i.e., pass it into an array function. In your example, you didn’t treat the columns as an array, so it just output the first record’s value which is the default behavior when you output myQry.myColumn outside of a query-based loop.


#4

I voted no based on that fact - I don’t think a function should have extra smarts to know how to process a variable differently


#5

Are we talking about the CFML dialect in Lucee here?

Then I could see a valid case for this to be adopted due to compatibility reasons, even though I’d personally agree with @webonix thinking it’s not really a good idea imho to all of a sudden treat a column as an array in certain circumstances.

This craziness should however not at all be supported in LuceeLang.


#6

Yes, this is the CFML dialect.

I don’t care for the duality either, but to be honest, I think it’s backwards. I dislike that myQry.myCol outside of a query-based loop doesn’t error. That fact that instead of getting an array back, you get the value of the first record is an “accident” IMO that leads to bugs and isn’t clear from the code.

I’m a little surprised that no one sees the current behavior as odd, but the column data as array is "craziness’ when it actually makes a great deal of sense. Just look at how CFML in either engine lets you reference a specific column and row outside of a loop:

myQry.amount[1]
myQry.amount[2]

The query object behaves like a struct of arrays and each column can be indexed just like it were an array. So the fact that you can then pass that column into an array function and do “array” things (in Adobe CF only) to it is pretty natural in my opinion as it follows the existing syntax. The fact that I can reference that “array-like” construct without an index outside a loop and get the first item back is craziness :slight_smile:


#7

It’s nothing to do with the function, it’s just type coercion and CFML does it all the time. This is a key facet of a loosely typed language.

If you pass a string to a function expecting a numeric; the CFML engine will attempt to convert the string to a numeric; same with the fairly ubiquitous behaviour of ppl passing strings-that-look-like-a-date-to-a-human to date functions, which expect date objects.

When one passes a query column to a function expecting a string, the query column resolves the type coercion by returning the value of the first row.

Whether or not it should do this is another thing - it is at odds with how complex objects are usually handled in this context (which is simply to raise an exception with saying you can’t do it) - but your basing your position on placing the cart before the horse.

That aside: it’s up to Adobe how CFML is supposed to behave, not LAS, so Lucee’s CFML implementation should just mirror ColdFusion’s behaviour. No good comes from not mirroring the behaviour in this context, and that should be one of the tests performed when “planning” any variation from how ColdFusion does stuff.


#8

Agreed.


#9

I agree with the consensus so far. Lucee CFML should implement it for compatibility. Lucee lang should rethink it all.

FWIW (though doesn’t detract from the argument), Lucee has:

ValueArray( myquery.mycolumn );

As far as I can make out, ACF does not have this.


#10

thanks for the clarifications and explanations
changed my vote


#11

Hmmm… I think I should perhaps raise an ER for this on the ColdFusion bugbase. It’s a much better way of extracting a column’s data (the rest of the discussion here notwithstanding). [quick search]… oh there already is one: https://bugbase.adobe.com/index.cfm?event=bug&id=3499033. Marked “to fix”. We should have it in ColdFusion by 2017 in that case :wink:


#12

Getting sidetracked here, but the comments on that ER are instructive. ValueArray() as in fact deprecated in favour of QueryColumnData(). I updated the docs whilst there:

http://docs.lucee.org/reference/functions/valuearray.html