This is a static copy of a profile report

Home

tabular.subsasgnDot (Calls: 800, Time: 0.143 s)
Generated 04-Jun-2021 04:11:14 using performance time.
function in file C:\Program Files\MATLAB\R2020b\toolbox\matlab\datatypes\tabular\@tabular\subsasgnDot.m
Copy to new window for comparing multiple runs

Parents (calling functions)

Function NameFunction TypeCalls
tabular.subsasgnfunction15
tabular.subsasgnBracesfunction785
Lines where the most time was spent

Line NumberCodeCallsTotal Time% TimeTime Plot
118
updatedVarDim = t.varDim.lengt...
7850.039 s27.2%
113
t.varDim.makeValidName(varName...
7850.019 s13.1%
68
t = t.setProperty(s(2:end),b);
120.017 s11.6%
60
if ~deleting && t.varD...
7970.009 s6.2%
480
t.rowDim = t.rowDim.lengthenTo...
7850.009 s6.1%
All other lines  0.051 s35.7%
Totals  0.143 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
varNamesDim>varNamesDim.lengthenToclass method7850.036 s25.0%
varNamesDim>varNamesDim.makeValidNameclass method7850.016 s11.1%
tabular.setPropertyfunction120.015 s10.4%
...Dim>varNamesDim.checkReservedNamesclass method7970.007 s4.7%
substructfunction7850.006 s4.1%
rowNamesDim>rowNamesDim.lengthenToclass method7850.005 s3.6%
tabular.lengthenTofunction7850.003 s2.2%
categorical.sizefunction60.001 s0.4%
Self time (built-ins, overhead, etc.)  0.055 s38.5%
Totals  0.143 s100% 
Code Analyzer results
No Code Analyzer messages.
Coverage results
Show coverage for parent directory
Total lines in function487
Non-code lines (comments, blank lines)212
Code lines (lines that can run)275
Code lines that did run60
Code lines that did not run215
Coverage (did run/can run)21.82 %
Function listing
time 
Calls 
 line
   1 
function t = subsasgnDot(t,s,b,deleting)
   2 
%SUBSASGNDOT Subscripted assignment to a table.
   3 

   4 
%   Copyright 2012-2019 The MathWorks, Inc.
   5 

   6 
% '.' is assignment to or into a variable.  Any sort of subscripting
   7 
% may follow that, and row labels are inherited from the table.
   8 

   9 
import matlab.internal.datatypes.emptyLike
  10 
import matlab.internal.datatypes.isCharString
  11 
import matlab.internal.datatypes.isColon
  12 
import matlab.internal.datatypes.isScalarInt
  13 
import matlab.lang.correction.ReplaceIdentifierCorrection
  14 
import matlab.lang.internal.move % Avoid unsharing of shared-data copy across function call boundary
  0.001 
    800 
  15
subsType = matlab.internal.tabular.private.tabularDimension.subsType; % "import" for calls to subs2inds 
  16 

  0.007 
    800 
  17
if ~isstruct(s), s = substruct('.',s); end 
  18 

  19 
% Check for deletion of entire variables, t.Var = [], or of columns/pages of a variable,
  20 
% t.Var(:,j) = []. deletion deeper that, e.g. t.Var(i).Field(...) = [] or t.Var{i}(...) = [],
  21 
% is handled by the assignment code path.
< 0.001 
    800 
  22
if nargin < 4 
  23 
    % Short-circuit for performance before calling _isEmptySqrBrktLiteral. isequal is
  24 
    % more expensive than isnumeric, but avoids _isEmptySqrBrktLiteral in more cases. For
  25 
    % built-in types, s(2).type=='()' guarantees that length(s)==2, but for a var that is
  26 
    % itself a table, parens need not be the end, so need to check that.
  0.002 
    800 
  27
    deleting = isnumeric(b) && isequal(b,[]) && builtin('_isEmptySqrBrktLiteral',b) ... 
  28 
        && (isscalar(s) || ((length(s) == 2) && isequal(s(2).type,'()')));
< 0.001 
    800 
  29
end 
  30 

< 0.001 
    800 
  31
t_nrows = t.rowDim.length; 
< 0.001 
    800 
  32
t_nvars = t.varDim.length; 
  33 

  34 
% Translate variable (column) name into an index. Avoid overhead of
  35 
% t.varDim.subs2inds as much as possible in this simple case.
  0.001 
    800 
  36
varName = convertStringsToChars(s(1).subs); 
< 0.001 
    800 
  37
if isnumeric(varName) 
  38 
    % Allow t.(i) where i is an integer
  39 
    varIndex = varName;
  40 
    if ~isScalarInt(varName,1)
  41 
        error(message('MATLAB:table:IllegalVarIndex'));
  42 
    end
  43 
    isNewVar = (varIndex > t_nvars);
  44 
    if isNewVar
  45 
        if deleting
  46 
            error(message('MATLAB:table:VarIndexOutOfRange'));
  47 
        elseif varIndex > t_nvars+1
  48 
            error(message('MATLAB:table:DiscontiguousVars'));
  49 
        else
  50 
            [~,~,~,~,~,updatedVarDim] = t.varDim.subs2inds(varIndex,subsType.assignment);
  51 
            varName = updatedVarDim.labels{varIndex};
  52 
        end
  53 
    end
< 0.001 
    800 
  54
elseif ischar(varName) && (isrow(varName) || isequal(varName,'')) % isCharString(varName) 
  0.004 
    800 
  55
    varIndex = find(matches(t.varDim.labels,varName)); 
< 0.001 
    800 
  56
    isNewVar = false; % assume for now, update below 
< 0.001 
    800 
  57
    if isempty(varIndex) 
  58 
        % Check against reserved names first as a failsafe against shadowing
  59 
        % .Properties by a dimension name.
  0.009 
    797 
  60
        if ~deleting && t.varDim.checkReservedNames(varName) % one name, don't need to wrap with any() 
  61 
            % Handle assignment to a property under the 'Properties' (virtual)
  62 
            % property, or to the entire 'Properties' property.
< 0.001 
     12 
  63
            if varName == "Properties" 
< 0.001 
     12 
  64
                try 
< 0.001 
     12 
  65
                    if isscalar(s) 
  66 
                        t = setProperties(t,b);
< 0.001 
     12 
  67
                    else 
  0.017 
     12 
  68
                        t = t.setProperty(s(2:end),b); 
< 0.001 
     12 
  69
                    end 
  70 
                catch ME
  71 
                    if ~isscalar(s) && (ME.identifier == "MATLAB:table:UnknownProperty")
  72 
                        propName = s(2).subs;
  73 
                        match = find(matches(t.propertyNames,propName,"IgnoreCase",true),1);
  74 
                        if ~isempty(match) % a property name. but with wrong case
  75 
                            match = t.propertyNames{match};
  76 
                            throw(MException(message('MATLAB:table:UnknownPropertyCase',propName,match)) ...
  77 
                            	.addCorrection(ReplaceIdentifierCorrection(propName,match)));
  78 
                        else
  79 
                            throw(ME);
  80 
                        end
  81 
                    else
  82 
                        throw(ME);
  83 
                    end
< 0.001 
     12 
  84
                end 
< 0.001 
     12 
  85
                return 
  86 
            elseif isColon(varName)
  87 
                error(message('MATLAB:table:ReservedVarnameColon'))                
  88 
            else % t.VariableNames or t.RowNames
  89 
                throw(MException(message('MATLAB:table:InvalidPropertyAssignment',varName)) ...
  90 
                	.addCorrection(ReplaceIdentifierCorrection(varName,append('Properties.',varName))));
  91 
            end
  0.002 
    785 
  92
        elseif matches(varName,t.metaDim.labels{1}) 
  93 
            % If it's the row dimension name, assign to the row labels
  94 
            varIndex = 0;
  95 
            % For assignments onto the row labels, accept any vector. For assignments
  96 
            % into, leave the RHS alone.
  97 
            if isscalar(s)
  98 
                if isvector(b), b = b(:); end
  99 
            elseif deleting % && ~isscalar(s)
 100 
                error(message('MATLAB:table:NestedSubscriptingWithDotRowsDeletion',t.metaDim.labels{1}));
 101 
            end
  0.001 
    785 
 102
        elseif matches(varName,t.metaDim.labels{2}) 
 103 
            % If it's the vars dimension name, assign to t{:,:}. Deeper subscripting
 104 
            % is not supported, use explicit braces for that.
 105 
            if ~isscalar(s)
 106 
                error(message('MATLAB:table:NestedSubscriptingWithDotVariables',t.metaDim.labels{2}));
 107 
            end
 108 
            varIndex = -1;
< 0.001 
    785 
 109
        elseif deleting 
 110 
            error(message('MATLAB:table:UnrecognizedVarNameDeleting',varName));
< 0.001 
    785 
 111
        else 
< 0.001 
    785 
 112
            isNewVar = true; 
  0.019 
    785 
 113
            t.varDim.makeValidName(varName,'error'); % error if invalid 
 114 

 115 
            % If this is a new variable, it will go at the end. Its name is guaranteed
 116 
            % to not conflict; it it did, we'd be assigning to an existing var.
< 0.001 
    785 
 117
            varIndex = t_nvars + 1; 
  0.039 
    785 
 118
            updatedVarDim = t.varDim.lengthenTo(varIndex,{varName}); 
< 0.001 
    785 
 119
        end 
< 0.001 
    788 
 120
    end 
 121 
else
 122 
    error(message('MATLAB:table:IllegalVarSubscript'));
< 0.001 
    788 
 123
end 
 124 

 125 
% Handle empty assignment intended as deletion of an entire variable or of
 126 
% columns/pages/etc. of a variable.  Deletion of rows in a (single)
 127 
% variable is caught here and not allowed.  Other empty assignment
 128 
% syntaxes may be assignment to cells or may be deletion of things deeper
 129 
% in a non-atomic variable, neither is handled here.
< 0.001 
    788 
 130
if deleting 
 131 
    % Syntax:  t.var = []
 132 
    %
 133 
    % Delete an entire variable.
 134 
    if isscalar(s)
 135 
        if varIndex > 0
 136 
            t.data(varIndex) = [];
 137 
            t.varDim = t.varDim.deleteFrom(varIndex);
 138 
        elseif varIndex == 0
 139 
            t.rowDim = t.rowDim.removeLabels(); % this might error
 140 
        else % varindex == -1
 141 
            varIndex = 1:t.varDim.length;
 142 
            t.data(varIndex) = [];
 143 
            t.varDim = t.varDim.deleteFrom(varIndex);
 144 
        end
 145 
    % Syntax:  t.var(:,...) = []
 146 
    %          t.var(rowIndices,...) = [] is illegal
 147 
    %
 148 
    % Delete columns/pages/etc. of a variable, with ':' as the first index
 149 
    % in subscript.  This may change the dimensionality of the variable,
 150 
    % but won't change the number of rows because we require ':' as the
 151 
    % first index.
 152 
    else % length(s) == 2
 153 
        % All vars in a table must have the same number of rows, so subscripted assignment
 154 
        % deletion on one var isn't allowed to remove rows: no linear indexing, and the
 155 
        % first subscript in 2- or N-D indexing, and all others except one, must be :.
 156 
        if isscalar(s(2).subs) ...
 157 
                || ~isColon(s(2).subs{1}) ...
 158 
                || all(cellfun(@isColon,s(2).subs))
 159 
            error(message('MATLAB:table:EmptyAssignmentToVariableRows'));
 160 
        end
 161 
        
 162 
        var_j = t.data{varIndex}; t.data{varIndex} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
 163 
        if isa(var_j,'tabular')
 164 
                % Use dot method to dispatch to overloaded table subscripting
 165 
                var_j = move(var_j).subsasgnParens(s(2),[],false,true);
 166 
        else
 167 
            var_j(s(2).subs{:}) = [];
 168 
        end
 169 
        t.data{varIndex} = var_j;
 170 
    end
 171 
    
< 0.001 
    788 
 172
else 
< 0.001 
    788 
 173
    updatedRowDim = []; 
 174 
    
 175 
    % Syntax:  t.var = b
 176 
    %
 177 
    % Replace an entire variable.  It must have the right number of rows, unless
 178 
    % the LHS is 0x0.
< 0.001 
    788 
 179
    if isscalar(s) 
  0.001 
    788 
 180
        if size(b,1) ~= t_nrows && (t_nrows+t_nvars > 0) 
 181 
            % If the assignment has the wrong number of rows, check for some
 182 
            % common mistakes to suggest what may have been intended
 183 
            if strcmpi(varName,'Properties') && ((isstruct(b) && isscalar(b)) || isa(b,'matlab.tabular.TabularProperties')) 
 184 
                % Things like t.properties = scalarStruct
 185 
                str = getString(message('MATLAB:table:IntendedPropertiesAssignment'));
 186 
                throw(MException(message('MATLAB:table:RowDimensionMismatchSuggest',str)) ...
 187 
                    .addCorrection(ReplaceIdentifierCorrection(varName,'Properties')));
 188 
            else
 189 
                match = find(strcmpi(varName,t.propertyNames),1);
 190 
                if ~isempty(match)
 191 
                    % Things like t.PropertyName = ...
 192 
                    match = t.propertyNames{match};
 193 
                    str = getString(message('MATLAB:table:IntendedPropertyAssignment',match));
 194 
                    throw(MException(message('MATLAB:table:RowDimensionMismatchSuggest',str)) ...
 195 
                    	.addCorrection(ReplaceIdentifierCorrection(varName,append('Properties.', match))));
 196 
                end
 197 
            end
 198 
            % Anything else, no suggestion. No point in checking for a case
 199 
            % insensitive match to an existing var, even with the correct case,
 200 
            % this would still be an illegal assignment
 201 
            error(message('MATLAB:table:RowDimensionMismatch'));
< 0.001 
    788 
 202
        end 
< 0.001 
    788 
 203
        var_j = b; 
 204 
        
 205 
    % Syntax:  t.var(rowIndices,...) = b
 206 
    %          t.var{rowIndices,...} = b
 207 
    %          t.var{rowIndices,...} = [] (this is assignment, not deletion)
 208 
    %          t.var.field = b
 209 
    %
 210 
    % Assign to elements in a variable.  Assignment can also be used to
 211 
    % expand the variable's number of rows, or along another dimension.
 212 
    %
 213 
    % Cell indexing, e.g. t.var{rowIndices,...}, or a reference to a
 214 
    % field, e.g. t.var.field, may also be followed by deeper levels of
 215 
    % subscripting. Cannot create a new var implicitly by deeper indexing.
 216 
    else % ~isscalar(s)
 217 
        if isNewVar && (length(s) > 2) && ~isequal(s(2).type,'.')
 218 
            % If the assignment is not to an existing var, check for some common
 219 
            % mistakes to suggest what may have been intended
 220 
            match = matches(t.varDim.labels,varName,'IgnoreCase',true);
 221 
            if any(match)
 222 
                % An existing variable name, but with wrong case
 223 
                match = t.varDim.labels{match};
 224 
                str = getString(message('MATLAB:table:IntendedVarAssignment',match));
 225 
                throw(MException(message('MATLAB:table:InvalidExpansionDotDepthSuggest',str)) ...
 226 
                    .addCorrection(ReplaceIdentifierCorrection(varName,match)));
 227 
            elseif matches(varName,t.metaDim.labels{1},'IgnoreCase',true)
 228 
                % The row dimension name, but with wrong case
 229 
                str = getString(message('MATLAB:table:IntendedRowDimAssignment',t.metaDim.labels{1}));
 230 
                throw(MException(message('MATLAB:table:InvalidExpansionDotDepthSuggest',str)) ...
 231 
                    .addCorrection(ReplaceIdentifierCorrection(varName,t.metaDim.labels{1})));
 232 
            end
 233 
            % Anything else, no suggestion
 234 
            error(message('MATLAB:table:InvalidExpansionDotDepth'));
 235 
        end
 236 
        
 237 
        if isequal(s(2).type,'.') % dot indexing into variable
 238 
            % If the assignment is not to an existing var, check for some common
 239 
            % mistakes to suggest what may have been intended
 240 
            if isNewVar
 241 
                if strcmpi(varName,'Properties') && isCharString(s(2).subs)
 242 
                    % Things like t.properties.name
 243 
                    str = getString(message('MATLAB:table:IntendedPropertiesAssignment'));
 244 
                    throw(MException(message('MATLAB:table:InvalidExpansionDotSuggest',str)) ...
 245 
                        .addCorrection(ReplaceIdentifierCorrection(varName,'Properties')));
 246 
                else
 247 
                    match = matches(t.varDim.labels,varName,'IgnoreCase',true);
 248 
                    if any(match)
 249 
                        % An existing variable name, but with wrong case
 250 
                        match = t.varDim.labels{match};
 251 
                        str = getString(message('MATLAB:table:IntendedVarAssignment',match));
 252 
                        throw(MException(message('MATLAB:table:InvalidExpansionDotSuggest',str)) ...
 253 
                        	.addCorrection(ReplaceIdentifierCorrection(varName,match)));
 254 
                    else
 255 
                        % Anything else, no suggestion
 256 
                        error(message('MATLAB:table:InvalidExpansionDot'));
 257 
                    end
 258 
                end
 259 
            end
 260 
            if varIndex > 0
 261 
                var_j = t.data{varIndex}; t.data{varIndex} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
 262 
            elseif varIndex == 0
 263 
                var_j = t.rowDim.labels;
 264 
            else % varIndex == -1
 265 
                assert(false);
 266 
            end
 267 
        else % () or {} subscripting into variable
 268 
            % Initialize a new var, or extract an existing var.
 269 
            if isNewVar
 270 
                % Start the new var out as an Nx0 empty of b's class, with the same
 271 
                % number of rows as the table.
 272 
                if isequal(s(2).type,'{}')
 273 
                    % {} subscripting on the new var indicates it should be a cell
 274 
                    % with contents being assigned.
 275 
                    var_j = cell(t_nrows,0);
 276 
                else
 277 
                    var_j = emptyLike([t_nrows,0],'Like',b);
 278 
                end
 279 
                
 280 
                % If the table has no rows, the new var was initialized as 0x0 and
 281 
                % a colon subscript in the first dim would be misinterpreted. Create
 282 
                % explicit row indices instead.
 283 
                if t_nrows == 0 && isColon(s(2).subs{1})
 284 
                    if t_nvars == 0
 285 
                        % If the table is 0x0, a colon subscript in the first dim should
 286 
                        % mean "height of the RHS". t.rowDim.subs2inds would think ':' means
 287 
                        % "height of t", so create explicit row indices to let it know how
 288 
                        % big : really is.
 289 
                        s(2).subs{1} = 1:size(b,1);
 290 
                    else
 291 
                        % Otherwise, a colon subscript in the first dim should mean "height
 292 
                        % of the table", and the RHS must have matching height. var_j is
 293 
                        % initialized to have t_nrows rows to match the table, but when t_nrows
 294 
                        % is 0, var_j is initialized as 0x0, and var_j's subsasgn would treat
 295 
                        % : as "height of the RHS" and not do the proper size checking. Create
 296 
                        % explicit row indices to make sure the RHS's height is checked.
 297 
                        %
 298 
                        s(2).subs{1} = 1:t_nrows;
 299 
                    end
 300 
                end
 301 
                % If the table has one or more rows, a colon subscript in the first dim always
 302 
                % means "height of the table", and that subscript can be left alone.
 303 
                
 304 
                % Convert any trailing colon subscripts into explicit indices with length
 305 
                % inherited from the RHS.
 306 
                for k = 2:length(s(2).subs)
 307 
                    if isColon(s(2).subs{k})
 308 
                        s(2).subs{k} = 1:size(b,k);
 309 
                    end
 310 
                end
 311 
            else
 312 
                if varIndex > 0
 313 
                    var_j = t.data{varIndex}; t.data{varIndex} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
 314 
                elseif varIndex == 0
 315 
                    var_j = t.rowDim.labels;
 316 
                else % varIndex == -1
 317 
                    assert(false);
 318 
                end
 319 
            end
 320 
            
 321 
            subs1 = s(2).subs{1};
 322 
            haveLabelSubscripts = ~(isnumeric(subs1) || islogical(subs1) || isColon(subs1));
 323 
            if haveLabelSubscripts
 324 
                % The variable inherits row labels from the table, translate to row indices. The
 325 
                % assignment may add rows, get the updated rowDim object with any new row labels. 
 326 
                % subs2inds returns the indices as a col vector, which prevents reshaping. This
 327 
                % is fine because the var is constrained inside the table.
 328 
                [s(2).subs{1},~,~,~,~,updatedRowDim] = t.rowDim.subs2inds(subs1,subsType.assignment);
 329 
                % There are some linear indexing cases that should have row semantics, or that
 330 
                % are not even legal. In those cases s(2).subs{1} can't be interpreted as row
 331 
                % labels and so calling t.rowDim.subs2inds returns something completely
 332 
                % meaningless. Those cases will be identified and caught immediately below.
 333 
            else
 334 
                % t.rowDim.subs2inds will leave rowSubscripts alone in these cases, other than
 335 
                % making it a column, so avoid calling it for performance. Leave updateRowDim
 336 
                % empty, only need that in the row labels case.
 337 
                s(2).subs{1} = subs1(:);
 338 
            end
 339 
            
 340 
            if isscalar(s(2).subs) % linear indexing into the LHS
 341 
                % If the LHS is linear indexing, e.g. t.var(indices) = b or t.var{indices} = b,
 342 
                % and new elements will be created, there are cases where we need to force it to
 343 
                % grow as a column vector, because it would try to grow as a row vector.
 344 
                %
 345 
                % If the var is
 346 
                %    a scalar or a 0x0
 347 
                %    a new var (which is initialized to Nx0, including possibly 1x0)
 348 
                %    an Nx0 (N>1) or 0xM (M>1) empty matrix
 349 
                % add a column index so it grows as a column vector.
 350 
                if isscalar(var_j)
 351 
                    s(2).subs = [s(2).subs {1}];
 352 
                elseif iscolumn(var_j) % including 0x1
 353 
                    % If the var is already a column, linear indexing will have column semantics,
 354 
                    % leave the subscript alone. A scalar is a column, but need to force it to
 355 
                    % behave like one, so catch those above.
 356 
                elseif all(size(var_j)==0) || isNewVar
 357 
                    % If indexing into LHS using s(2).subs yeilds a non-empty output or we are adding
 358 
                    % a new var then update s(2).subs to ensure that var grows as a column vector.
 359 
                    if isNewVar || isNonEmptySubscript(s(2).subs{1})
 360 
                        s(2).subs = [s(2).subs {1}];
 361 
                    end
 362 
                elseif ismatrix(var_j) && isempty(var_j) && ~isrow(var_j) % Nx0 or 0xM, excluding 1x0
 363 
                    % If indexing into LHS using s(2).subs yeilds a non-empty output then update
 364 
                    % s(2).subs to ensure that var grows as a column vector.
 365 
                    if isNonEmptySubscript(s(2).subs{1})
 366 
                        % This case is analogous to what would happen in the workspace, except in table
 367 
                        % the assignment creates a column instead of a row.
 368 
                        s(2).subs = [s(2).subs {1}];
 369 
                        var_j = var_j(:); % make it a 0x1 column to be safe
 370 
                    end
 371 

 372 
                % By now var_j must be a row (possibly 1x0), a non-empty matrix, or an N-D array.
 373 
                elseif haveLabelSubscripts
 374 
                    % Numeric, logical, and colon subscripts have unambiguous meaning as in linear
 375 
                    % indexing regardless of the shape of the var being assigned into. But row
 376 
                    % labels have meaning only for column semantics, i.e. only if the var is already
 377 
                    % a column (including a 0x1), or if we've added a column index to force the
 378 
                    % result of the assignment to _become_ a column. Otherwise, linear indexing with
 379 
                    % row labels is an error.
 380 
                    error(message('MATLAB:table:InvalidLinearIndexing'));
 381 
                else
 382 
                    % If the var is a row, linear indexing has row semantics, let that happen.
 383 
                    % If the var is a non-empty matrix, or any N-D array, assignment using linear
 384 
                    % indexing is an ambiguous dimension error, let that happen at the actual
 385 
                    % assignment.
 386 
                end
 387 
            end
 388 
        end
 389 
        
 390 
        % Now let the variable's subsasgn handle the subscripting in
 391 
        % things like t.name(...) or  t.name{...} or t.name.attribute
 392 
        
 393 
        if length(s) == 2
 394 
            % If b is a built-in type, or the same class as var_j, call subsasgn directly
 395 
            % for fastest dispatch to var_j's (possibly overloaded) subscripting. Otherwise,
 396 
            % force dispatch to var_j's subscripting even when b is dominant. In most cases,
 397 
            % calling subsasgn via builtin guarantees dispatch on the first input. However,
 398 
            % if var_j is a table, builtin would dispatch to default, not overloaded,
 399 
            % subscripting, so use dot-method syntax.
 400 
            if isobject(b)
 401 
                if isa(var_j,class(b)) % var_j first is fast when it is built-in
 402 
                    var_j = subsasgn(var_j,s(2),b); % dispatches correctly, even to tabular
 403 
                elseif isa(var_j,'tabular')
 404 
                    var_j = move(var_j).subsasgn(s(2),b);
 405 
                else
 406 
                    var_j = builtin('subsasgn',var_j,s(2),b);
 407 
                end
 408 
            else
 409 
                % If the RHS of the assignment into the table was a literal [], and the LHS
 410 
                % target is t.Var or t.Var(...), that's already been recognized as subscripted
 411 
                % assignment deletion, and handled correctly. A RHS that is a 0x0 double but not
 412 
                % a literal [] should be treated as a genuine assignment, but the built-in
 413 
                % subsasgn called here treats that as deletion when the LHS is a built-in type
 414 
                % subscripted with (). Happily, assignment of any other empty double will have
 415 
                % the desired effect, so turn b into a 0x1. The same must be done for '' (which
 416 
                % "is equal" to []) to prevent it from deleting.
 417 
                if isequal(b,[]) && ~isobject(var_j) && isequal(s(2).type,'()')
 418 
                    % One exception: subscripted assignment deletion other than t.Var=[] or
 419 
                    % t.Var(...)=[], such as t.Var(i).Field(...)=[] or t.Var{i}(...)=[], ends up
 420 
                    % here for delegation to var_j, so don't replace a RHS that _is_ a literal [].
 421 
                    if ischar(b) || ~builtin('_isEmptySqrBrktLiteral',b), b = b(:); end
 422 
                end
 423 
                var_j = subsasgn(move(var_j),s(2),b);
 424 
            end
 425 
        else % length(s) > 2
 426 
            % Trick the third and higher levels of subscripting in things like
 427 
            % t.Var{i}(...) etc. into dispatching to the right place even when
 428 
            % t.Var{i}, or something further down the chain, is itself a table.
 429 
            if isequal(b,[]) && isequal(s(end).type,'()')
 430 
                if ischar(b) || ~builtin('_isEmptySqrBrktLiteral',b), b = b(:); end
 431 
            end
 432 
            var_j = matlab.internal.tabular.private.subsasgnRecurser(move(var_j),s(2:end),b);
 433 
        end
< 0.001 
    788 
 434
    end 
 435 
    
 436 
    % If this is a new variable, make it official.
< 0.001 
    788 
 437
    if isNewVar 
  0.006 
    785 
 438
        t.varDim = updatedVarDim; 
< 0.001 
    788 
 439
    end 
 440 
    
 441 
    % If an entire var was replaced or created, the new value was required to have
 442 
    % the same number of rows as the table.  However, when assigning _into_ a new
 443 
    % var, the assignment might create something shorter than the table, so check
 444 
    % for that and tallen the new var to match the table. Also, assigning into an
 445 
    % existing var that is Nx0 using linear indexing will turn it into a col that
 446 
    % might be shorter, so tallen it to match the table, but don't warn since that's
 447 
    % an implementation artifact. (Assigning into an existing var that is 0xM using
 448 
    % linear indexing will also turn it into a col, but it can never be shorter.)
 449 
    % (Historically, a var could also get shorter by assigning a field to a
 450 
    % non-struct, or by assigning via a direct call to subsasgn into new elements of
 451 
    % _any_ matrix using linear indexing. Neither works that way now. Those would
 452 
    % have gotten fixed here too.)
< 0.001 
    788 
 453
    varLen = size(var_j,1); 
< 0.001 
    788 
 454
    if varLen < t_nrows % t's original number of rows 
 455 
        if isNewVar
 456 
            warning(message('MATLAB:table:RowsAddedNewVars'));
 457 
        end
 458 
        var_j = t.lengthenVar(var_j,t_nrows);
< 0.001 
    788 
 459
    end 
< 0.001 
    788 
 460
    if varIndex > 0 
  0.008 
    788 
 461
        t.data{varIndex} = var_j; 
 462 
    elseif varIndex == 0
 463 
        t.rowDim = t.rowDim.setLabels(var_j);
 464 
    else % varIndex == -1
 465 
        t = t.subsasgnBraces({':' ':'},var_j);
< 0.001 
    788 
 466
    end 
 467 
    
 468 
    % If the var being assigned to is now taller than the table, add rows to
 469 
    % the rest of the table, including row labels.  This might be because the
 470 
    % assignment lengthened an existing var, or because an "into" assignment
 471 
    % created a new var taller than the table.  Warn only if we have to lengthen
 472 
    % existing vars that have not been assigned to -- if there's currently only
 473 
    % one var in the table (which might be existing or new), don't warn about
 474 
    % any default values "filled in in the middle".
< 0.001 
    788 
 475
    if varLen > t_nrows % t's original number of rows 
< 0.001 
    785 
 476
        if t.varDim.length > 1 % some existing vars were not assigned to 
 477 
            warning(message('MATLAB:table:RowsAddedExistingVars'));
< 0.001 
    785 
 478
        end 
< 0.001 
    785 
 479
        if isempty(updatedRowDim) 
  0.009 
    785 
 480
            t.rowDim = t.rowDim.lengthenTo(varLen); 
 481 
        else
 482 
            t.rowDim = updatedRowDim;
< 0.001 
    785 
 483
        end 
  0.005 
    785 
 484
        t = t.lengthenTo(varLen); % updates nrows 
< 0.001 
    788 
 485
    end 
< 0.001 
    788 
 486
end 
  0.002 
    788 
 487
end 

Other subfunctions in this file are not included in this listing.