Forum Stats

  • 3,874,091 Users
  • 2,266,678 Discussions
  • 7,911,723 Comments

Discussions

Allow default values for object attributes

William Robertson
William Robertson Member Posts: 9,568 Bronze Crown
edited Jan 19, 2016 1:05PM in Database Ideas - Ideas

There are quite a few things I'd like to see added to the PL/SQL OO implementation such as encapsulation (which so many people have been requesting for the last decade and a half that I'm not going to bother), but I came up against one restriction this week that should be pretty simple to fix.

In PL/SQL we can define default values for procedure arguments:

procedure someproc
    ( p_someparam integer default 0 )









and in SQL we can set default values for columns (so the SQL language already has a concept of default values):

create table log
    ( log_timestamp timestamp default systimestamp













but we can't do this for a type:

create or replace type test_t as object
    ( some_attribute integer default 0 ) LINE/COL  ERROR
---------- ---------------------------------------------------------------------------------------------------
0/0        PL/SQL: Compilation unit analysis terminated
2/3        PLS-00363: expression 'SOME_ATTRIBUTE' cannot be used as an assignment target

Yet this is possible in other languages. In Swift for example you can do this:

struct Fahrenheit {
    var temperature = 32.0
}

In Scala you can do this:

class HashMap[K,V](initialCapacity:Int = 16, loadFactor:Float = 0.75f) {
}

In Ada 2012 you can set both defaults and valid ranges:

type OK is new Boolean
    with Default_Value => True;






type Location is
    record
      X: My_Float range –1.0 .. +1.0 := 0.0;
      Y: My_Float range  –1.0 .. +1.0;
    end record;






Unless I am missing something (comments please if I am) this would remove the need for a lot of constructor code.

BPeaslandDBACloudDBApexBineSven W.fac586Zlatko SiroticulohmannNaeel MaqsudovUser_D09BV
11 votes

Active · Last Updated

Comments

  • Unknown
    edited Jan 20, 2016 11:41PM
    Unless I am missing something (comments please if I am) this would remove the need for a lot of constructor code.
    

    Yes - I believe you are missing at least TWO things:

    1. types are typically used in SQL

    2. Oracle distinguishes between a type specification and a type body.

    create or replace type test_t as object 
        ( some_attribute integer default 0 ) 

    That is just the spec for the type.

    Then, by default, Oracle will create an 'attribute-value' constructor. That constructor REQUIRES that you specify EVERY attribute value when you use it.

    You don't have to actually define a type body - you will get the bare minimum functionality.

    If some attributes had a default then you would have the extra burden of using the same type of parameter spec needed when you use pl/sql functions/procedures. That can get messy - especially if you needed to use 'named parameter' notation:

    create or replace type test_t as object
        ( some_attribute integer )  
    
    select test_t(some_attribute=> 3) from dual
    

    Would you REALLY want to have to specify the names of ALL of the attributes EXCEPT the ones that have defaults?

    How would that work in SQL? Would you REALLY want to have to specify all of those attribute names in your sql statement?

    You can easily create a type body if you need more complex functionality. Then you can specify as many constructors as you want and those constructors can initialize any attributes to a default value if you choose.

    I don't see any substantial benefit to having a 'default' value. But I see a lot of issues changing the current underlying processes to support it.

    I'd much rather see Oracle devote there time and resources to other areas where the need and payout is much higher.

  • William Robertson
    William Robertson Member Posts: 9,568 Bronze Crown
    Unless I am missing something (comments please if I am) this would remove the need for a lot of constructor code.
    

    Yes - I believe you are missing at least TWO things:

    1. types are typically used in SQL

    2. Oracle distinguishes between a type specification and a type body.

    create or replace type test_t as object 
        ( some_attribute integer default 0 ) 

    That is just the spec for the type.

    Then, by default, Oracle will create an 'attribute-value' constructor. That constructor REQUIRES that you specify EVERY attribute value when you use it.

    You don't have to actually define a type body - you will get the bare minimum functionality.

    If some attributes had a default then you would have the extra burden of using the same type of parameter spec needed when you use pl/sql functions/procedures. That can get messy - especially if you needed to use 'named parameter' notation:

    create or replace type test_t as object
        ( some_attribute integer )  
    
    select test_t(some_attribute=> 3) from dual
    

    Would you REALLY want to have to specify the names of ALL of the attributes EXCEPT the ones that have defaults?

    How would that work in SQL? Would you REALLY want to have to specify all of those attribute names in your sql statement?

    You can easily create a type body if you need more complex functionality. Then you can specify as many constructors as you want and those constructors can initialize any attributes to a default value if you choose.

    I don't see any substantial benefit to having a 'default' value. But I see a lot of issues changing the current underlying processes to support it.

    I'd much rather see Oracle devote there time and resources to other areas where the need and payout is much higher.

    Yes, it's true that the default constructor expects a parameter for every attribute which would then override the default, so as you point out, unless we use named notation to specify just the ones we want to set, or else write our own constructor, then a default value isn't much use - and if we write our own constructor then we can set defaults there.

    I still think there are cases where all or most attributes could be set to explicit, self-documenting defaults, like the examples from other languages, or where you find yourself needing multiple constructors and having to write a common initialiser procedure called from all constructors (as I've just needed to do for my loader_t() type to set self.rows_loaded = 0 etc).

    I've only rarely seen types used in SQL personally, but I don't think that affects the issue much.