Re: ANALYZE command [REPOST]

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: ANALYZE command [REPOST]
Дата
Msg-id 200104250214.f3P2EIv03762@candle.pha.pa.us
обсуждение исходный текст
Ответ на ANALYZE command [REPOST]  (Fernando Nasser <fnasser@cygnus.com>)
Список pgsql-patches
I will keep this for possible inclusing in 7.2.  Thanks.

> [My apologies: I forgot to tell to which sources the patch applies, as required and, which is worse, I attached the
wrongpatch;  I have corrected it now.] 
>
>
> This patch is a follow-up to the split of the vacuum and analyze (done by Bruce Momjian last year).  I applies to
today'sCVS sources. 
>
> It adds a separate SQL extension command ANALYZE that will only perform the analyze part and thus only use shared
locks.
>
> I will submit the doc and test changes in a separate patch, if you decide that we are really going ahead with the
ANALYZEcommand. 
>
> This version still does not update pg_class.  Those statistics are still tied in the vacuum part (num. of pages,
tuplesand indication if the relation has an index).  The patch allows for analyze_rel() to work differently if run as
partof a VACUUM or as an standalone ANALYZE, so the missing bits can be added without changes to the current 
> behavior of VACUUM ANALYZE.
>
> Possible future improvements:
>
> 1) Add the pg_class update to ANALYZE;
>
> 2) Add a VERBOSE option that prints information to gives the DBA a hint if it is worth of running VACUUM or not.
>
> Thanks.
>
>
> --
> Fernando Nasser
> Red Hat Inc.              E-Mail:  fnasser@redhat.com

> Index: src/backend/commands/analyze.c
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/commands/analyze.c,v
> retrieving revision 1.16
> diff -c -p -r1.16 analyze.c
> *** src/backend/commands/analyze.c    2001/03/22 06:16:11    1.16
> --- src/backend/commands/analyze.c    2001/04/24 22:22:24
> ***************
> *** 35,41 ****
> --- 35,46 ----
>   #include "utils/fmgroids.h"
>   #include "utils/inval.h"
>   #include "utils/syscache.h"
> + #include "utils/temprel.h"
>
> + static MemoryContext vac_context = NULL;
> +
> + static int    MESSAGE_LEVEL;        /* message level */
> +
>   #define swapLong(a,b)    {long tmp; tmp=a; a=b; b=tmp;}
>   #define swapInt(a,b)    {int tmp; tmp=a; a=b; b=tmp;}
>   #define swapDatum(a,b)    {Datum tmp; tmp=a; a=b; b=tmp;}
> *************** static void attr_stats(Relation onerel,
> *** 49,61 ****
>   static void bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int *bucket_len);
>   static void update_attstats(Oid relid, int natts, VacAttrStats *vacattrstats);
>   static void del_stats(Oid relid, int attcnt, int *attnums);
>
>
>   /*
>    *    analyze_rel() -- analyze relation
>    */
>   void
> ! analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
>   {
>       HeapTuple    tuple;
>       Relation    onerel;
> --- 54,175 ----
>   static void bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int *bucket_len);
>   static void update_attstats(Oid relid, int natts, VacAttrStats *vacattrstats);
>   static void del_stats(Oid relid, int attcnt, int *attnums);
> + static void do_analyze(NameData *VacRelP, List *anal_cols2);
> + static void analyze_rel_1(Oid relid, List *anal_cols2, int vacuum);
> +
> +
> + void
> + analyze(char *vacrel, List *anal_cols)
> + {
> +     NameData    VacRel;
> +     Name        VacRelName;
> +     MemoryContext old;
> +     List       *le;
> +     List       *anal_cols2 = NIL;
> +
> +     /*
> +      * We cannot run ANALYZE inside a user transaction block; if we were
> +      * inside a transaction, then our commit- and
> +      * start-transaction-command calls would not have the intended effect!
> +      */
> +     if (IsTransactionBlock())
> +         elog(ERROR, "ANALYZE cannot run inside a BEGIN/END block");
> +
> +     MESSAGE_LEVEL = DEBUG;
>
> +     /*
> +      * Create special memory context for cross-transaction storage.
> +      *
> +      * Since it is a child of QueryContext, it will go away eventually even
> +      * if we suffer an error; there's no need for special abort cleanup
> +      * logic.
> +      */
> +     vac_context = AllocSetContextCreate(QueryContext,
> +                                         "Analyze",
> +                                         ALLOCSET_DEFAULT_MINSIZE,
> +                                         ALLOCSET_DEFAULT_INITSIZE,
> +                                         ALLOCSET_DEFAULT_MAXSIZE);
> +
> +     /* vacrel gets de-allocated on xact commit, so copy it to safe storage */
> +     if (vacrel)
> +     {
> +         namestrcpy(&VacRel, vacrel);
> +         VacRelName = &VacRel;
> +     }
> +     else
> +         VacRelName = NULL;
>
> +     /* must also copy the column list, if any, to safe storage */
> +     old = MemoryContextSwitchTo(vac_context);
> +     foreach(le, anal_cols)
> +     {
> +         char       *col = (char *) lfirst(le);
> +
> +         anal_cols2 = lappend(anal_cols2, pstrdup(col));
> +     }
> +     MemoryContextSwitchTo(old);
> +
> +     /*
> +      * Start up the analyzer.
> +      *
> +      * NOTE: since this commits the current transaction, the memory holding
> +      * any passed-in parameters gets freed here.  We must have already
> +      * copied pass-by-reference parameters to safe storage.  Don't make me
> +      * fix this again!
> +      */
> +     vacuum_init();
> +
> +     /* analyze the database */
> +     do_analyze(VacRelName, anal_cols2);
> +
> +     vacuum_shutdown(vac_context);
> + }
> +
>   /*
> +  *    do_analyze() -- analyze the database.
> +  *
> +  *        This routine builds a list of relations to analyze, and then calls
> +  *        code that analyze them one at a time.
> +  */
> + static void
> + do_analyze(NameData *VacRelP, List *anal_cols2)
> + {
> +     VRelList    vrl,
> +                 cur;
> +
> +     /* get list of relations */
> +     vrl = vacuum_getrels(VacRelP, vac_context);
> +
> +     /* analyze each heap relation */
> +     for (cur = vrl; cur != (VRelList) NULL; cur = cur->vrl_next)
> +     {
> +         analyze_rel_1(cur->vrl_relid, anal_cols2, 0 /* not vacuum */);
> +     }
> + }
> +
> + /*
>    *    analyze_rel() -- analyze relation
> +  *
> +  *    Called through here when doing vacuum
>    */
>   void
> ! analyze_rel(Oid relid, List *anal_cols2, int msg_level)
> ! {
> !     /*
> !      * Use the MESSAGE_LEVEL as set on vacuum.
> !      */
> !     MESSAGE_LEVEL = msg_level;
> !     analyze_rel_1(relid, anal_cols2, 1 /* vacuum */);
> ! }
> !
> ! /*
> !  *    analyze_rel_1() -- analyze relation
> !  *
> !  *    Do the job for ANALYZE or VACUUM ANALYSE in one relation
> !  */
> !
> ! static void
> ! analyze_rel_1(Oid relid, List *anal_cols2, int vacuum)
>   {
>       HeapTuple    tuple;
>       Relation    onerel;
> *************** analyze_rel(Oid relid, List *anal_cols2,
> *** 107,116 ****
>       {
>
>           /*
> !          * we already did an elog during vacuum elog(NOTICE, "Skipping
> !          * \"%s\" --- only table owner can VACUUM it",
> !          * RelationGetRelationName(onerel));
>            */
>           heap_close(onerel, NoLock);
>           CommitTransactionCommand();
>           return;
> --- 221,231 ----
>       {
>
>           /*
> !          * we already did an elog during vacuum
>            */
> +         if (!vacuum)
> +             elog(NOTICE, "Skipping \"%s\" --- only table owner can ANALYZE it",
> +                  RelationGetRelationName(onerel));
>           heap_close(onerel, NoLock);
>           CommitTransactionCommand();
>           return;
> *************** analyze_rel(Oid relid, List *anal_cols2,
> *** 127,133 ****
>           List       *le;
>
>           if (length(anal_cols2) > attr_cnt)
> !             elog(ERROR, "vacuum: too many attributes specified for relation %s",
>                    RelationGetRelationName(onerel));
>           attnums = (int *) palloc(attr_cnt * sizeof(int));
>           foreach(le, anal_cols2)
> --- 242,248 ----
>           List       *le;
>
>           if (length(anal_cols2) > attr_cnt)
> !             elog(ERROR, "analyze: too many attributes specified for relation %s",
>                    RelationGetRelationName(onerel));
>           attnums = (int *) palloc(attr_cnt * sizeof(int));
>           foreach(le, anal_cols2)
> *************** analyze_rel(Oid relid, List *anal_cols2,
> *** 143,149 ****
>                   attnums[tcnt++] = i;
>               else
>               {
> !                 elog(ERROR, "vacuum: there is no attribute %s in %s",
>                        col, RelationGetRelationName(onerel));
>               }
>           }
> --- 258,264 ----
>                   attnums[tcnt++] = i;
>               else
>               {
> !                 elog(ERROR, "analyze: there is no attribute %s in %s",
>                        col, RelationGetRelationName(onerel));
>               }
>           }
> Index: src/backend/commands/vacuum.c
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/commands/vacuum.c,v
> retrieving revision 1.189
> diff -c -p -r1.189 vacuum.c
> *** src/backend/commands/vacuum.c    2001/03/25 23:23:58    1.189
> --- src/backend/commands/vacuum.c    2001/04/24 22:22:25
> *************** static int    MESSAGE_LEVEL;        /* message le
> *** 60,69 ****
>   static TransactionId XmaxRecent;
>
>   /* non-export function prototypes */
> - static void vacuum_init(void);
> - static void vacuum_shutdown(void);
>   static void vac_vacuum(NameData *VacRelP, bool analyze, List *anal_cols2);
> - static VRelList getrels(NameData *VacRelP);
>   static void vacuum_rel(Oid relid);
>   static void scan_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages);
>   static void repair_frag(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList
fraged_pages,int nindices, Relation *Irel); 
> --- 60,66 ----
> *************** vacuum(char *vacrel, bool verbose, bool
> *** 163,169 ****
>       vac_vacuum(VacRelName, analyze, anal_cols2);
>
>       /* clean up */
> !     vacuum_shutdown();
>   }
>
>   /*
> --- 160,166 ----
>       vac_vacuum(VacRelName, analyze, anal_cols2);
>
>       /* clean up */
> !     vacuum_shutdown(vac_context);
>   }
>
>   /*
> *************** vacuum(char *vacrel, bool verbose, bool
> *** 186,200 ****
>    *        vacuum_shutdown() to match the commit waiting for us back in
>    *        PostgresMain().
>    */
> ! static void
>   vacuum_init()
>   {
>       /* matches the StartTransaction in PostgresMain() */
>       CommitTransactionCommand();
>   }
>
> ! static void
> ! vacuum_shutdown()
>   {
>       /* on entry, we are not in a transaction */
>
> --- 183,197 ----
>    *        vacuum_shutdown() to match the commit waiting for us back in
>    *        PostgresMain().
>    */
> ! void
>   vacuum_init()
>   {
>       /* matches the StartTransaction in PostgresMain() */
>       CommitTransactionCommand();
>   }
>
> ! void
> ! vacuum_shutdown(MemoryContext context)
>   {
>       /* on entry, we are not in a transaction */
>
> *************** vacuum_shutdown()
> *** 218,224 ****
>        * StartTransactionCommand, else we might be trying to delete the
>        * active context!
>        */
> !     MemoryContextDelete(vac_context);
>       vac_context = NULL;
>   }
>
> --- 215,221 ----
>        * StartTransactionCommand, else we might be trying to delete the
>        * active context!
>        */
> !     MemoryContextDelete(context);
>       vac_context = NULL;
>   }
>
> *************** vac_vacuum(NameData *VacRelP, bool analy
> *** 237,243 ****
>                   cur;
>
>       /* get list of relations */
> !     vrl = getrels(VacRelP);
>
>       /* vacuum each heap relation */
>       for (cur = vrl; cur != (VRelList) NULL; cur = cur->vrl_next)
> --- 234,240 ----
>                   cur;
>
>       /* get list of relations */
> !     vrl = vacuum_getrels(VacRelP, vac_context);
>
>       /* vacuum each heap relation */
>       for (cur = vrl; cur != (VRelList) NULL; cur = cur->vrl_next)
> *************** vac_vacuum(NameData *VacRelP, bool analy
> *** 249,256 ****
>       }
>   }
>
> ! static VRelList
> ! getrels(NameData *VacRelP)
>   {
>       Relation    rel;
>       TupleDesc    tupdesc;
> --- 246,253 ----
>       }
>   }
>
> ! VRelList
> ! vacuum_getrels(NameData *VacRelP, MemoryContext context)
>   {
>       Relation    rel;
>       TupleDesc    tupdesc;
> *************** getrels(NameData *VacRelP)
> *** 317,327 ****
>           /* get a relation list entry for this guy */
>           if (vrl == (VRelList) NULL)
>               vrl = cur = (VRelList)
> !                 MemoryContextAlloc(vac_context, sizeof(VRelListData));
>           else
>           {
>               cur->vrl_next = (VRelList)
> !                 MemoryContextAlloc(vac_context, sizeof(VRelListData));
>               cur = cur->vrl_next;
>           }
>
> --- 314,324 ----
>           /* get a relation list entry for this guy */
>           if (vrl == (VRelList) NULL)
>               vrl = cur = (VRelList)
> !                 MemoryContextAlloc(context, sizeof(VRelListData));
>           else
>           {
>               cur->vrl_next = (VRelList)
> !                 MemoryContextAlloc(context, sizeof(VRelListData));
>               cur = cur->vrl_next;
>           }
>
> Index: src/backend/nodes/copyfuncs.c
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v
> retrieving revision 1.140
> diff -c -p -r1.140 copyfuncs.c
> *** src/backend/nodes/copyfuncs.c    2001/03/22 06:16:14    1.140
> --- src/backend/nodes/copyfuncs.c    2001/04/24 22:22:25
> *************** _copyVacuumStmt(VacuumStmt *from)
> *** 2218,2223 ****
> --- 2218,2235 ----
>       return newnode;
>   }
>
> + static AnalyzeStmt *
> + _copyAnalyzeStmt(AnalyzeStmt *from)
> + {
> +     AnalyzeStmt *newnode = makeNode(AnalyzeStmt);
> +
> +     if (from->anarel)
> +         newnode->anarel = pstrdup(from->anarel);
> +     Node_Copy(from, newnode, va_spec);
> +
> +     return newnode;
> + }
> +
>   static ExplainStmt *
>   _copyExplainStmt(ExplainStmt *from)
>   {
> *************** copyObject(void *from)
> *** 2780,2785 ****
> --- 2792,2800 ----
>               break;
>           case T_RemoveOperStmt:
>               retval = _copyRemoveOperStmt(from);
> +             break;
> +         case T_AnalyzeStmt:
> +             retval = _copyAnalyzeStmt(from);
>               break;
>           case T_RenameStmt:
>               retval = _copyRenameStmt(from);
> Index: src/backend/nodes/equalfuncs.c
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v
> retrieving revision 1.88
> diff -c -p -r1.88 equalfuncs.c
> *** src/backend/nodes/equalfuncs.c    2001/03/22 03:59:31    1.88
> --- src/backend/nodes/equalfuncs.c    2001/04/24 22:22:25
> *************** _equalVacuumStmt(VacuumStmt *a, VacuumSt
> *** 1126,1131 ****
> --- 1126,1142 ----
>   }
>
>   static bool
> + _equalAnalyzeStmt(AnalyzeStmt *a, AnalyzeStmt *b)
> + {
> +     if (!equalstr(a->anarel, b->anarel))
> +         return false;
> +     if (!equal(a->va_spec, b->va_spec))
> +         return false;
> +
> +     return true;
> + }
> +
> + static bool
>   _equalExplainStmt(ExplainStmt *a, ExplainStmt *b)
>   {
>       if (!equal(a->query, b->query))
> *************** equal(void *a, void *b)
> *** 1946,1951 ****
> --- 1957,1965 ----
>               break;
>           case T_RemoveOperStmt:
>               retval = _equalRemoveOperStmt(a, b);
> +             break;
> +         case T_AnalyzeStmt:
> +             retval = _equalAnalyzeStmt(a, b);
>               break;
>           case T_RenameStmt:
>               retval = _equalRenameStmt(a, b);
> Index: src/backend/parser/gram.y
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/gram.y,v
> retrieving revision 2.221
> diff -c -p -r2.221 gram.y
> *** src/backend/parser/gram.y    2001/02/18 18:06:10    2.221
> --- src/backend/parser/gram.y    2001/04/24 22:22:26
> *************** static void doNegateFloat(Value *v);
> *** 130,135 ****
> --- 130,136 ----
>
>   %type <node>    stmt,
>           AlterGroupStmt, AlterSchemaStmt, AlterTableStmt, AlterUserStmt,
> +         AnalyzeStmt, CheckPointStmt,
>           ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
>           CopyStmt, CreateAsStmt, CreateGroupStmt, CreatePLangStmt,
>           CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
> *************** static void doNegateFloat(Value *v);
> *** 142,148 ****
>           RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
>           RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
>           UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt,
> !         VariableSetStmt, VariableShowStmt, ViewStmt, CheckPointStmt
>
>   %type <node>    select_no_parens, select_with_parens, select_clause,
>                   simple_select
> --- 143,149 ----
>           RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
>           RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
>           UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt,
> !         VariableSetStmt, VariableShowStmt, ViewStmt
>
>   %type <node>    select_no_parens, select_with_parens, select_clause,
>                   simple_select
> *************** stmt :    AlterSchemaStmt
> *** 426,431 ****
> --- 427,433 ----
>           | AlterTableStmt
>           | AlterGroupStmt
>           | AlterUserStmt
> +         | AnalyzeStmt
>           | ClosePortalStmt
>           | CopyStmt
>           | CreateStmt
> *************** va_list:  name
> *** 3037,3042 ****
> --- 3039,3074 ----
>                   { $$ = makeList1($1); }
>           | va_list ',' name
>                   { $$ = lappend($1, $3); }
> +         ;
> +
> +
> + /*****************************************************************************
> +  *
> +  *        QUERY:
> +  *                analyze
> +  *
> +  *****************************************************************************/
> +
> + /* We use opt_va_list and va_list defined for vacuum. */
> +
> + AnalyzeStmt:  ANALYZE
> +                                 {
> +                                         AnalyzeStmt *n = makeNode(AnalyzeStmt);
> +                                         n->anarel = NULL;
> +                                         n->va_spec = NIL;
> +                                         $$ = (Node *)n;
> +                                 }
> +                 | ANALYZE relation_name opt_va_list
> +                 {
> +                     AnalyzeStmt *n = makeNode(AnalyzeStmt);
> +                     n->anarel = $2;
> +                     n->va_spec = $3;
> +                     if ( $3 != NIL && !$2 )
> +                         elog(ERROR,"ANALYZE syntax error at or near \"(\""
> +                             "\n\tRelation name must be specified");
> +
> +                     $$ = (Node *)n;
> +                 }
>           ;
>
>
> Index: src/backend/tcop/utility.c
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/tcop/utility.c,v
> retrieving revision 1.109
> diff -c -p -r1.109 utility.c
> *** src/backend/tcop/utility.c    2001/03/22 06:16:17    1.109
> --- src/backend/tcop/utility.c    2001/04/24 22:22:26
> *************** ProcessUtility(Node *parsetree,
> *** 711,716 ****
> --- 711,723 ----
>                      ((VacuumStmt *) parsetree)->va_spec);
>               break;
>
> +         case T_AnalyzeStmt:
> +             set_ps_display(commandTag = "ANALYZE");
> +
> +             analyze(((AnalyzeStmt *) parsetree)->anarel,
> +                    ((AnalyzeStmt *) parsetree)->va_spec);
> +             break;
> +
>           case T_ExplainStmt:
>               {
>                   ExplainStmt *stmt = (ExplainStmt *) parsetree;
> Index: src/include/commands/vacuum.h
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/commands/vacuum.h,v
> retrieving revision 1.34
> diff -c -p -r1.34 vacuum.h
> *** src/include/commands/vacuum.h    2001/03/22 04:00:43    1.34
> --- src/include/commands/vacuum.h    2001/04/24 22:22:29
> *************** extern bool VacuumRunning;
> *** 122,127 ****
> --- 122,131 ----
>
>   extern void vc_abort(void);
>   extern void vacuum(char *vacrel, bool verbose, bool analyze, List *anal_cols);
> + extern void vacuum_init(void);
> + extern void vacuum_shutdown(MemoryContext vac_context);
> + extern VRelList vacuum_getrels(NameData *VacRelP, MemoryContext vac_context);
> + extern void analyze(char *vacrel, List *anal_cols);
>   extern void analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL);
>
>   #define ATTNVALS_SCALE    1000000000        /* XXX so it can act as a float4 */
> Index: src/include/nodes/nodes.h
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/nodes/nodes.h,v
> retrieving revision 1.89
> diff -c -p -r1.89 nodes.h
> *** src/include/nodes/nodes.h    2001/04/24 00:08:38    1.89
> --- src/include/nodes/nodes.h    2001/04/24 22:22:29
> *************** typedef enum NodeTag
> *** 165,171 ****
>       T_RemoveAggrStmt,
>       T_RemoveFuncStmt,
>       T_RemoveOperStmt,
> !     T_RemoveStmt_XXX,            /* not used anymore; tag# available */
>       T_RenameStmt,
>       T_RuleStmt,
>       T_NotifyStmt,
> --- 165,171 ----
>       T_RemoveAggrStmt,
>       T_RemoveFuncStmt,
>       T_RemoveOperStmt,
> !     T_AnalyzeStmt,
>       T_RenameStmt,
>       T_RuleStmt,
>       T_NotifyStmt,
> Index: src/include/nodes/parsenodes.h
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/nodes/parsenodes.h,v
> retrieving revision 1.126
> diff -c -p -r1.126 parsenodes.h
> *** src/include/nodes/parsenodes.h    2001/03/23 04:49:56    1.126
> --- src/include/nodes/parsenodes.h    2001/04/24 22:22:29
> *************** typedef struct VacuumStmt
> *** 703,708 ****
> --- 703,719 ----
>   } VacuumStmt;
>
>   /* ----------------------
> +  *        Analyze Statement
> +  * ----------------------
> +  */
> + typedef struct AnalyzeStmt
> + {
> +     NodeTag        type;
> +     char       *anarel;            /* table to analyze */
> +     List       *va_spec;        /* columns to analyse */
> + } AnalyzeStmt;
> +
> + /* ----------------------
>    *        Explain Statement
>    * ----------------------
>    */
> Index: src/interfaces/ecpg/preproc/preproc.y
> ===================================================================
> RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/ecpg/preproc/preproc.y,v
> retrieving revision 1.136
> diff -c -p -r1.136 preproc.y
> *** src/interfaces/ecpg/preproc/preproc.y    2001/04/05 08:21:14    1.136
> --- src/interfaces/ecpg/preproc/preproc.y    2001/04/24 22:22:30
> *************** make_name(void)
> *** 302,308 ****
>   %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
>   %type  <str>    opt_with_copy FetchStmt direction fetch_how_many from_in
>   %type  <str>    ClosePortalStmt DropStmt VacuumStmt opt_verbose func_arg
> ! %type  <str>    opt_analyze opt_va_list va_list ExplainStmt index_params
>   %type  <str>    index_list func_index index_elem opt_class access_method_clause
>   %type  <str>    index_opt_unique IndexStmt func_return ConstInterval
>   %type  <str>    func_args_list func_args opt_with ProcedureStmt def_arg
> --- 302,308 ----
>   %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
>   %type  <str>    opt_with_copy FetchStmt direction fetch_how_many from_in
>   %type  <str>    ClosePortalStmt DropStmt VacuumStmt opt_verbose func_arg
> ! %type  <str>    opt_analyze opt_va_list va_list AnalyzeStmt ExplainStmt index_params
>   %type  <str>    index_list func_index index_elem opt_class access_method_clause
>   %type  <str>    index_opt_unique IndexStmt func_return ConstInterval
>   %type  <str>    func_args_list func_args opt_with ProcedureStmt def_arg
> *************** stmt:  AlterSchemaStmt             { output_state
> *** 447,452 ****
> --- 447,453 ----
>           | CreatedbStmt        { output_statement($1, 0, NULL, connection); }
>           | DropdbStmt        { output_statement($1, 0, NULL, connection); }
>           | VacuumStmt        { output_statement($1, 0, NULL, connection); }
> +         | AnalyzeStmt        { output_statement($1, 0, NULL, connection); }
>           | VariableSetStmt    { output_statement($1, 0, NULL, connection); }
>           | VariableShowStmt    { output_statement($1, 0, NULL, connection); }
>           | VariableResetStmt    { output_statement($1, 0, NULL, connection); }
> *************** va_list:  name
> *** 2282,2287 ****
> --- 2283,2310 ----
>                   { $$=$1; }
>           | va_list ',' name
>                   { $$=cat_str(3, $1, make_str(","), $3); }
> +         ;
> +
> +
> + /*****************************************************************************
> +  *
> +  *        QUERY:
> +  *                analyze
> +  *
> +  *****************************************************************************/
> +
> + /* We use opt_va_list and va_list defined for vacuum. */
> +
> + AnalyzeStmt:  ANALYZE
> +                 {
> +                     $$ = cat_str(1, make_str("analyze"));
> +                 }
> +         | ANALYZE relation_name opt_va_list
> +                 {
> +                     if ( strlen($3) > 0 && strlen($2) == 0 )
> +                         mmerror(ET_ERROR, "ANALYZE syntax error at or near \"(\"\n\tRelations name must be
specified");
> +                     $$ = cat_str(3, make_str("analyze"), $2, $3);
> +                 }
>           ;
>
>

>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

В списке pgsql-patches по дате отправления:

Предыдущее
От: Fernando Nasser
Дата:
Сообщение: ANALYZE command [REPOST]
Следующее
От: Tom Lane
Дата:
Сообщение: Re: ANALYZE command [REPOST]