Beispiel #1
0
 static bool NameInUsingClause(IdList using_, string colName)
 {
     if (using_ != null)
         for (int k = 0; k < using_.Ids.length; k++)
             if (string.Compare(using_.Ids[k].Name, colName, StringComparison.OrdinalIgnoreCase) == 0) return true;
     return false;
 }
Beispiel #2
0
 /*
 ** pEList is the SET clause of an UPDATE statement.  Each entry
 ** in pEList is of the format <id>=<expr>.  If any of the entries
 ** in pEList have an <id> which matches an identifier in pIdList,
 ** then return TRUE.  If pIdList==NULL, then it is considered a
 ** wildcard that matches anything.  Likewise if pEList==NULL then
 ** it matches anything so always return true.  Return false only
 ** if there is no match.
 */
 static int checkColumnOverlap(IdList pIdList, ExprList pEList)
 {
     int e;
     if (pIdList == null || NEVER(pEList == null))
         return 1;
     for (e = 0; e < pEList.nExpr; e++)
     {
         if (sqlite3IdListIndex(pIdList, pEList.a[e].zName) >= 0)
             return 1;
     }
     return 0;
 }
        public static void RenderResults(HtmlWriter writer, SearchRecord[] records, bool renderUl = true)
        {
            var visibleCategorizations = CategorizationFolder.GetVisibleCategorizations();
            var newsListUrl = Urls.GetMainNewsListUrl();

            if (renderUl)
                writer.RenderBeginTag(HtmlTextWriterTag.Ul, "news-list");
            foreach (var record in records)
            {
                var date = record.GetDate("date");

                writer.RenderBeginTag(HtmlTextWriterTag.Li, "clearfix");

                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                writer.AddAttribute(HtmlTextWriterAttribute.Href, record.GetString("url"));
                writer.RenderBeginTag(HtmlTextWriterTag.A);
                writer.RenderFullTag(HtmlTextWriterTag.H3, record.GetString("title"));
                writer.RenderEndTag(); // a
                if (date != null)
                    writer.RenderFullTag(HtmlTextWriterTag.Span,
                                         "Publiseret " + record.GetDate("date").Value.ToString("dd-MM-yyyy"), "date");

                var categorizations = new IdList(record.GetString("categorizations"));
                if (categorizations.Any())
                {
                    RenderCategorizations(writer, categorizations, visibleCategorizations, newsListUrl);
                }
                writer.RenderBeginTag(HtmlTextWriterTag.A);

                var text = record.GetString("summary");
                if (text.Length > 150)
                    text = text.Substring(0, 150);
                writer.RenderFullTag(HtmlTextWriterTag.P, text);

                writer.RenderEndTag(); // a
                writer.RenderEndTag(); // div
                writer.RenderEndTag(); // li.clearfix
            }
            if (renderUl)
                writer.RenderEndTag();
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            AjaxUtil.RegisterPageMethods(this);

            if (!string.IsNullOrEmpty(Request.QueryString["frame"]))
            {
                ClientScript.RegisterStartupScript(Page.GetType(), "editorInitialization", @"
                var gridEditorFrame = $('#" + Request.QueryString["frame"] + @"', window.parent.document);
                gridEditorFrame.parent().css('clear','both');
                ", true);
            }

            editor.Attributes.Add("hiddenId", Request.QueryString["hiddenId"]);

            var provider = GetProvider();
            var sourceNodes = provider.GetRootNodes().ToList();
            var destinationNodes = new List<Node>();
            using (CmsContext.Editing)
            {
                var item = CmsService.Instance.GetItem<Entity>(new Id(Request.QueryString["itemId"]));
                var fieldName = Request.QueryString["fieldName"];
                var value = new IdList(item[fieldName]);
                foreach (var id in value)
                {
                    var node = sourceNodes.Where(n => n.Id == id.ToString()).FirstOrDefault();
                    if (node != null)
                    {
                        sourceNodes.Remove(node);
                        destinationNodes.Add(node);
                    }
                }
                var litSource = new Literal();
                litSource.Text = "<ul class=\"srcList listbox\">" + multiListControl.GenerateListBox(sourceNodes) + "</ul>";
                multiListControl.Initialize(litSource, destinationNodes);

            }
        }
Beispiel #5
0
        protected override void CreateChildControls()
        {
            var provider = GetProvider();

            using (CmsContext.Editing)
            {
                var item = CmsService.Instance.GetItem<Entity>(new Id(Request.QueryString["itemId"]));
                var fieldName = Request.QueryString["fieldName"];
                var value = new IdList(item[fieldName]);
                var destinationNodes = value.Select(id => provider.GetNode(id.ToString())).Where(node => node != null).ToArray();

                var treeview = new LinqItTreeView();
                treeview.Provider = Request.QueryString["provider"];
                treeview.ProviderReferenceId = Request.QueryString["itemId"];

                var placeholder = new PlaceHolder();
                placeholder.Controls.Add(new LiteralControl("<div class=\"srcList \">"));
                placeholder.Controls.Add(treeview);
                placeholder.Controls.Add(new LiteralControl("</div>"));

                multiListControl.Initialize(placeholder, destinationNodes);
            }
            base.CreateChildControls();
        }
        /// <summary>
        /// Creates an XmlElement representing an Epi Info 7 view's data.
        /// </summary>
        /// <param name="xmlDataPackage">The data package xml document that the XmlElement should be added to</param>
        /// <param name="form">The form whose data will be serialized</param>
        /// <returns>XmlElement; represents the form's data in Xml format, suitable for use in data packaging</returns>
        protected override XmlElement CreateXmlFormDataElement(XmlDocument xmlDataPackage, View form)
        {
            #region Input Validation
            if (xmlDataPackage == null)
            {
                throw new ArgumentNullException("xmlDataPackage");
            }
            if (form == null)
            {
                throw new ArgumentNullException("form");
            }
            #endregion // Input Validation

            XmlElement data = xmlDataPackage.CreateElement("Data");

            OnStatusChanged(String.Format("Packaging data for form {0}...", form.Name));
            OnResetProgress();

            /* This seems like an usual set of steps to just iterate over the data. The problem is that we can't "just
             * iterate over the data" - the data is split up page tables, with one table representing one page on the
             * form. While a JOIN might be able to bring everything together into one table, it might not - for example,
             * if there are >255 fields after the JOIN, an OleDb exception will be thrown.
             *
             * To get around this issue: The code first iterates over the rows in the BASE TABLE, obtaining the GUID
             * values for each. The GUIDs and their corresponding XmlElement go into a dictionary.
             *
             * Later, each row in each page is iterated over; as the GUIDs for each page table are accessed, the corresponding
             * XmlElement is pulled from the dictionary. Field data is added to it for each field that has data. In this
             * manner, it doesn't matter that each row is technically accessed out-of-order because they'll still show up
             * in-order in the resulting Xml.
             *
             * Filtering adds another layer of complexity. To filter, a JOIN operation is needed so that the filters can
             * be applied across all those tables, since the fields in the filter may be across different tables. The
             * RowFilter class provides a way to handle this; we simply get the query from that object and apply it to the
             * reader. Only GUIDs that match the filter are added to the dictionary of guids.
             */

            // We need to exclude records from child forms that may now be orphaned as a result of a filter applied to the parent
            if (form.IsRelatedView && PreviousDistanceFromRoot < CurrentDistanceFromRoot)
            {
                ParentIdList.Clear();
                foreach (KeyValuePair <string, XmlElement> kvp in IdList)
                {
                    ParentIdList.Add(kvp.Key);
                }
            }

            IdList.Clear(); // Very important, this needs to be re-set in case we've already processed a form (this is a class level variable)

            if (!ExportInfo.RecordsPackaged.ContainsKey(form))
            {
                ExportInfo.RecordsPackaged.Add(form, 0);
            }

            //bool filterThisForm = false;
            RowFilters filters     = null;
            Query      selectQuery = null;

            IDbDriver db = SourceProject.CollectedData.GetDatabase();

            string recStatusClause = String.Empty;

            if (Filters != null && Filters.ContainsKey(form.Name) && Filters[form.Name].Count() > 0)
            {
                //filterThisForm = true;
                filters = Filters[form.Name];
                filters.RecordProcessingScope = RecordProcessingScope;
                selectQuery = filters.GetGuidSelectQuery(form);

                List <QueryParameter> paramsToAdd = selectQuery.Parameters;
                selectQuery            = db.CreateQuery(selectQuery.SqlStatement.Replace("[t].[GlobalRecordId], [t].[FKEY], [t].[RECSTATUS]", "*"));
                selectQuery.Parameters = paramsToAdd;
            }
            else
            {
                recStatusClause = "RECSTATUS = 1";

                if (RecordProcessingScope == Epi.RecordProcessingScope.Both)
                {
                    recStatusClause = "RECSTATUS >= 0";
                }
                else if (RecordProcessingScope == Epi.RecordProcessingScope.Deleted)
                {
                    recStatusClause = "RECSTATUS = 0";
                }

                string selectQueryText = "SELECT * " + form.FromViewSQL;

                selectQueryText = "SELECT * " + form.FromViewSQL + " WHERE " + recStatusClause;
                selectQuery     = db.CreateQuery(selectQueryText);
            }

            double totalRecords = Convert.ToDouble(db.ExecuteScalar(db.CreateQuery("SELECT COUNT(*) FROM " + form.TableName)));

            var fieldInclusionList = new List <RenderableField>();

            foreach (Field field in form.Fields)
            {
                if (field is IDataField && field is RenderableField && !(field is GridField) && !(FieldsToNull.ContainsKey(form.Name) && FieldsToNull[form.Name].Contains(field.Name)))
                {
                    var fieldToAdd = field as RenderableField;
                    if (fieldToAdd != null)
                    {
                        fieldInclusionList.Add(fieldToAdd);
                    }
                }
            }

            int processedRecords = 0;

            //using (IDataReader guidReader = db.ExecuteReader(selectQuery))
            //using (IDataReader guidReader = filterThisForm ? db.ExecuteReader(selectQuery) : db.GetTableDataReader(form.TableName))

            DataTable fullTable = db.Select(selectQuery);

            //int lowKey = (int)db.ExecuteScalar(db.CreateQuery("SELECT Min(UniqueKey) FROM " + form.TableName));
            //int highKey = (int)db.ExecuteScalar(db.CreateQuery("SELECT Max(UniqueKey) FROM " + form.TableName));

            ////ProcessRows(fullTable.Select("UniqueKey >= " + lowKey + " AND UniqueKey <= " + (highKey / 4)), form, xmlDataPackage, fieldInclusionList);

            string set1 = String.Empty;
            //string set2 = String.Empty;
            //string set3 = String.Empty;
            //string set4 = String.Empty;

            //Parallel.Invoke(
            //    () =>
            //    {
            set1 = ProcessRows(fullTable.Rows, form, xmlDataPackage, fieldInclusionList);
            //},
            //() =>
            //{
            //    set2 = ProcessRows(fullTable.Select("UniqueKey >= " + (highKey / 4) + " AND UniqueKey < " + (highKey / 2)), form, xmlDataPackage, fieldInclusionList);
            //},
            //() =>
            //{
            //    set3 = ProcessRows(fullTable.Select("UniqueKey >= " + (highKey / 2) + " AND UniqueKey < " + (highKey / 1.5)), form, xmlDataPackage, fieldInclusionList);
            //},
            //() =>
            //{
            //    set4 = ProcessRows(fullTable.Select("UniqueKey >= " + (highKey / 1.5) + " AND UniqueKey <= " + highKey), form, xmlDataPackage, fieldInclusionList);
            //}
            //);

            //StringBuilder sb = new StringBuilder();

            //foreach (XmlElement element in set1)
            //{
            //    sb.Append(element.OuterXml);
            //    //data.AppendChild(element);
            //}

            //foreach (XmlElement element in set2)
            //{
            //    sb.Append(element.OuterXml);
            //    //data.AppendChild(element);
            //}

            //foreach (XmlElement element in set3)
            //{
            //    sb.Append(element.OuterXml);
            //    //data.AppendChild(element);
            //}

            //foreach (XmlElement element in set4)
            //{
            //    sb.Append(element.OuterXml);
            //    //data.AppendChild(element);
            //}

            data.InnerText = set1;

            return(data);


            foreach (DataRow guidReader in fullTable.Rows)
            {
                //using(var conn = new System.Data.SqlClient.SqlConnection(db.ConnectionString + ";Connection Timeout=10"))
                //{
                //    conn.Open();

                //    using (var selectCommand = new System.Data.SqlClient.SqlCommand(selectQueryText, conn))
                //    {
                //        using (var guidReader = selectCommand.ExecuteReader())
                //        {
                //            while (guidReader.Read())
                //            {
                string   guid            = guidReader["GlobalRecordId"].ToString();// guidReader.GetString(0); // guidReader["GlobalRecordId"].ToString();
                string   fkey            = guidReader["FKEY"].ToString();
                string   recstatus       = guidReader["RECSTATUS"].ToString();
                string   firstSaveUserId = String.Empty;
                DateTime?firstSaveTime   = null;
                string   lastSaveUserId  = String.Empty;
                DateTime?lastSaveTime    = null;

                firstSaveUserId = guidReader["FirstSaveLogonName"].ToString();
                if (guidReader["FirstSaveTime"] != DBNull.Value)
                {
                    firstSaveTime = (DateTime)guidReader["FirstSaveTime"];
                }
                lastSaveUserId = guidReader["LastSaveLogonName"].ToString();
                if (guidReader["LastSaveTime"] != DBNull.Value)
                {
                    lastSaveTime = (DateTime)guidReader["LastSaveTime"];
                }

                if (!form.IsRelatedView || ParentIdList.Contains(fkey))
                {
                    XmlElement   record = xmlDataPackage.CreateElement("Record");
                    XmlAttribute id     = xmlDataPackage.CreateAttribute("Id");
                    id.Value = guid;
                    record.Attributes.Append(id);

                    if (!string.IsNullOrEmpty(fkey))
                    {
                        XmlAttribute foreignKey = xmlDataPackage.CreateAttribute("Fkey");
                        foreignKey.Value = fkey;
                        record.Attributes.Append(foreignKey);
                    }
                    if (!string.IsNullOrEmpty(firstSaveUserId))
                    {
                        XmlAttribute firstSaveId = xmlDataPackage.CreateAttribute("FirstSaveUserId");
                        firstSaveId.Value = firstSaveUserId;
                        record.Attributes.Append(firstSaveId);
                    }
                    if (!string.IsNullOrEmpty(lastSaveUserId))
                    {
                        XmlAttribute lastSaveId = xmlDataPackage.CreateAttribute("LastSaveUserId");
                        lastSaveId.Value = lastSaveUserId;
                        record.Attributes.Append(lastSaveId);
                    }
                    if (firstSaveTime.HasValue)
                    {
                        XmlAttribute firstSaveDateTime = xmlDataPackage.CreateAttribute("FirstSaveTime");
                        firstSaveDateTime.Value = firstSaveTime.Value.Ticks.ToString();
                        record.Attributes.Append(firstSaveDateTime);
                    }
                    if (lastSaveTime.HasValue)
                    {
                        XmlAttribute lastSaveDateTime = xmlDataPackage.CreateAttribute("LastSaveTime");
                        lastSaveDateTime.Value = lastSaveTime.Value.Ticks.ToString();
                        record.Attributes.Append(lastSaveDateTime);
                    }
                    if (!String.IsNullOrEmpty(recstatus))
                    {
                        XmlAttribute recStatusAttribute = xmlDataPackage.CreateAttribute("RecStatus");
                        recStatusAttribute.Value = recstatus;
                        record.Attributes.Append(recStatusAttribute);
                    }
                    IdList.Add(guid, record);

                    ExportInfo.TotalRecordsPackaged++;
                    ExportInfo.RecordsPackaged[form]++;

                    foreach (RenderableField field in fieldInclusionList)
                    {
                        XmlElement fieldData = xmlDataPackage.CreateElement("Field");

                        XmlAttribute name = xmlDataPackage.CreateAttribute("Name");
                        name.Value = field.Name;
                        fieldData.Attributes.Append(name);

                        string value = guidReader[field.Name].ToString();

                        if (!String.IsNullOrEmpty(value))
                        {
                            if (field is DateTimeField)
                            {
                                DateTime dt = Convert.ToDateTime(value);
                                fieldData.InnerText = dt.Ticks.ToString();
                            }
                            else if (field is ImageField)
                            {
                                value = Convert.ToBase64String((Byte[])guidReader[field.Name]);
                                fieldData.InnerText = value;
                            }
                            else if (field is NumberField)
                            {
                                value = Convert.ToDouble(value).ToString(System.Globalization.CultureInfo.InvariantCulture);
                                fieldData.InnerText = value;
                            }
                            else
                            {
                                fieldData.InnerText = value;
                            }
                        }

                        if (String.IsNullOrEmpty(fieldData.InnerText) && IncludeNullFieldData == false)
                        {
                            // do nothing, for now...
                        }
                        else
                        {
                            record.AppendChild(fieldData);
                        }
                        data.AppendChild(record);
                    }
                }

                processedRecords++;
                double progress = (((double)processedRecords) / ((double)totalRecords)) * 100;
                OnProgressChanged(progress);
            }

            foreach (GridField gridField in form.Fields.GridFields)
            {
                data.AppendChild(CreateXmlGridElement(xmlDataPackage, form, gridField));
                ExportInfo.GridsProcessed++;
            }

            return(data);
        }
Beispiel #7
0
 static TriggerStep sqlite3TriggerInsertStep( sqlite3 db, Token pTableName, IdList pColumn, int null_4, Select pSelect, u8 orconf )
 {
   return sqlite3TriggerInsertStep( db, pTableName, pColumn, null, pSelect, orconf );
 }
Beispiel #8
0
    /*
    ** This is called by the parser when it sees a CREATE TRIGGER statement
    ** up to the point of the BEGIN before the trigger actions.  A Trigger
    ** structure is generated based on the information available and stored
    ** in pParse.pNewTrigger.  After the trigger actions have been parsed, the
    ** sqlite3FinishTrigger() function is called to complete the trigger
    ** construction process.
    */
    static void sqlite3BeginTrigger(
    Parse pParse,      /* The parse context of the CREATE TRIGGER statement */
    Token pName1,      /* The name of the trigger */
    Token pName2,      /* The name of the trigger */
    int tr_tm,         /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
    int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
    IdList pColumns,   /* column list if this is an UPDATE OF trigger */
    SrcList pTableName,/* The name of the table/view the trigger applies to */
    Expr pWhen,        /* WHEN clause */
    int isTemp,        /* True if the TEMPORARY keyword is present */
    int noErr          /* Suppress errors if the trigger already exists */
    )
    {
      Trigger pTrigger = null;      /* The new trigger */
      Table pTab;                   /* Table that the trigger fires off of */
      string zName = null;          /* Name of the trigger */
      sqlite3 db = pParse.db;       /* The database connection */
      int iDb;                      /* The database to store the trigger in */
      Token pName = null;           /* The unqualified db name */
      DbFixer sFix = new DbFixer(); /* State vector for the DB fixer */
      int iTabDb;                   /* Index of the database holding pTab */

      Debug.Assert( pName1 != null );   /* pName1.z might be NULL, but not pName1 itself */
      Debug.Assert( pName2 != null );
      Debug.Assert( op == TK_INSERT || op == TK_UPDATE || op == TK_DELETE );
      Debug.Assert( op > 0 && op < 0xff );
      if ( isTemp != 0 )
      {
        /* If TEMP was specified, then the trigger name may not be qualified. */
        if ( pName2.n > 0 )
        {
          sqlite3ErrorMsg( pParse, "temporary trigger may not have qualified name" );
          goto trigger_cleanup;
        }
        iDb = 1;
        pName = pName1;
      }
      else
      {
        /* Figure out the db that the the trigger will be created in */
        iDb = sqlite3TwoPartName( pParse, pName1, pName2, ref pName );
        if ( iDb < 0 )
        {
          goto trigger_cleanup;
        }
      }
      if ( null == pTableName ) //|| db.mallocFailed 
      {
        goto trigger_cleanup;
      }

      /* A long-standing parser bug is that this syntax was allowed:
      **
      **    CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
      **                                                 ^^^^^^^^
      **
      ** To maintain backwards compatibility, ignore the database
      ** name on pTableName if we are reparsing our of SQLITE_MASTER.
      */
      if ( db.init.busy != 0 && iDb != 1 )
      {
        //sqlite3DbFree( db, pTableName.a[0].zDatabase );
        pTableName.a[0].zDatabase = null;
      }

      /* If the trigger name was unqualified, and the table is a temp table,
      ** then set iDb to 1 to create the trigger in the temporary database.
      ** If sqlite3SrcListLookup() returns 0, indicating the table does not
      ** exist, the error is caught by the block below.
      */
      if ( pTableName == null /*|| db.mallocFailed != 0 */ )
      {
        goto trigger_cleanup;
      }
      pTab = sqlite3SrcListLookup( pParse, pTableName );
      if ( db.init.busy == 0 && pName2.n == 0 && pTab != null
            && pTab.pSchema == db.aDb[1].pSchema )
      {
        iDb = 1;
      }

      /* Ensure the table name matches database name and that the table exists */
      //      if ( db.mallocFailed != 0 ) goto trigger_cleanup;
      Debug.Assert( pTableName.nSrc == 1 );
      if ( sqlite3FixInit( sFix, pParse, iDb, "trigger", pName ) != 0 &&
      sqlite3FixSrcList( sFix, pTableName ) != 0 )
      {
        goto trigger_cleanup;
      }
      pTab = sqlite3SrcListLookup( pParse, pTableName );
      if ( pTab == null )
      {
        /* The table does not exist. */
        if ( db.init.iDb == 1 )
        {
          /* Ticket #3810.
          ** Normally, whenever a table is dropped, all associated triggers are
          ** dropped too.  But if a TEMP trigger is created on a non-TEMP table
          ** and the table is dropped by a different database connection, the
          ** trigger is not visible to the database connection that does the
          ** drop so the trigger cannot be dropped.  This results in an
          ** "orphaned trigger" - a trigger whose associated table is missing.
          */
          db.init.orphanTrigger = 1;
        }
        goto trigger_cleanup;
      }
      if ( IsVirtual( pTab ) )
      {
        sqlite3ErrorMsg( pParse, "cannot create triggers on virtual tables" );
        goto trigger_cleanup;
      }

      /* Check that the trigger name is not reserved and that no trigger of the
      ** specified name exists */
      zName = sqlite3NameFromToken( db, pName );
      if ( zName == null || SQLITE_OK != sqlite3CheckObjectName( pParse, zName ) )
      {
        goto trigger_cleanup;
      }
      Debug.Assert( sqlite3SchemaMutexHeld( db, iDb, null ) );
      if ( sqlite3HashFind( ( db.aDb[iDb].pSchema.trigHash ),
      zName, sqlite3Strlen30( zName ), (Trigger)null ) != null )
      {
        if ( noErr == 0 )
        {
          sqlite3ErrorMsg( pParse, "trigger %T already exists", pName );
        }
        else
        {
          Debug.Assert( 0==db.init.busy );
          sqlite3CodeVerifySchema( pParse, iDb );
        }
        goto trigger_cleanup;
      }

      /* Do not create a trigger on a system table */
      if ( pTab.zName.StartsWith( "sqlite_", System.StringComparison.InvariantCultureIgnoreCase ) )
      {
        sqlite3ErrorMsg( pParse, "cannot create trigger on system table" );
        pParse.nErr++;
        goto trigger_cleanup;
      }

      /* INSTEAD of triggers are only for views and views only support INSTEAD
      ** of triggers.
      */
      if ( pTab.pSelect != null && tr_tm != TK_INSTEAD )
      {
        sqlite3ErrorMsg( pParse, "cannot create %s trigger on view: %S",
        ( tr_tm == TK_BEFORE ) ? "BEFORE" : "AFTER", pTableName, 0 );
        goto trigger_cleanup;
      }
      if ( pTab.pSelect == null && tr_tm == TK_INSTEAD )
      {
        sqlite3ErrorMsg( pParse, "cannot create INSTEAD OF" +
        " trigger on table: %S", pTableName, 0 );
        goto trigger_cleanup;
      }
      iTabDb = sqlite3SchemaToIndex( db, pTab.pSchema );

#if !SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_CREATE_TRIGGER;
string zDb = db.aDb[iTabDb].zName;
string zDbTrig = isTemp ? db.aDb[1].zName : zDb;
if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, zName, pTab.zName, zDbTrig) ){
goto trigger_cleanup;
}
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
goto trigger_cleanup;
}
}
#endif

      /* INSTEAD OF triggers can only appear on views and BEFORE triggers
** cannot appear on views.  So we might as well translate every
** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
** elsewhere.
*/
      if ( tr_tm == TK_INSTEAD )
      {
        tr_tm = TK_BEFORE;
      }

      /* Build the Trigger object */
      pTrigger = new Trigger();// (Trigger*)sqlite3DbMallocZero( db, sizeof(Trigger ))
      if ( pTrigger == null )
        goto trigger_cleanup;
      pTrigger.zName = zName;
      pTrigger.table = pTableName.a[0].zName;// sqlite3DbStrDup( db, pTableName.a[0].zName );
      pTrigger.pSchema = db.aDb[iDb].pSchema;
      pTrigger.pTabSchema = pTab.pSchema;
      pTrigger.op = (u8)op;
      pTrigger.tr_tm = tr_tm == TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
      pTrigger.pWhen = sqlite3ExprDup( db, pWhen, EXPRDUP_REDUCE );
      pTrigger.pColumns = sqlite3IdListDup( db, pColumns );
      Debug.Assert( pParse.pNewTrigger == null );
      pParse.pNewTrigger = pTrigger;

trigger_cleanup:
      sqlite3DbFree( db, ref zName );
      sqlite3SrcListDelete( db, ref pTableName );
      sqlite3IdListDelete( db, ref pColumns );
      sqlite3ExprDelete( db, ref pWhen );
      if ( pParse.pNewTrigger == null )
      {
        sqlite3DeleteTrigger( db, ref pTrigger );
      }
      else
      {
        Debug.Assert( pParse.pNewTrigger == pTrigger );
      }
    }
Beispiel #9
0
        static string Example5()
        {
            NamedReg x1 = new NamedReg();
            x1.name = "x1";

            NamedReg x2 = new NamedReg();
            x2.name = "x2";

            IdList idl1 = new IdList();
            idl1.Add(x1);
            idl1.Add(x2);

            LocalDecl ld1 = new LocalDecl();
            ld1.type = new NumType();
            ld1.id_list = idl1;

            AtomExprList ael1 = new AtomExprList();
            ael1.Add(x1);
            ael1.Add(x2);

            ReturnStmt rs1 = new ReturnStmt();
            rs1.rv = ael1;

            StmtList sl1 = new StmtList();
            sl1.Add(ld1);
            sl1.Add(rs1);

            Sub abc = new Sub("abc", sl1);

            Pirate p = new Pirate();
            p.Add(abc);

            StringWriter sw = new StringWriter();
            PirateWriter pv = new PirateWriter(sw);

            DynamicVisitor.accept(p, pv);

            return sw.ToString();
        }
Beispiel #10
0
        static string Example3()
        {
            Pirate p = new Pirate();

            StmtList sl1 = new StmtList();

            Sub joe = new Sub("joe", sl1);

            p.Add(joe);

            LocalDecl ld1 = new LocalDecl();
            ld1.type = new StringType();

            NamedReg name = new NamedReg();
            name.name = "name";
            IdList idl1 = new IdList();
            idl1.Add(name);

            ld1.id_list = idl1;

            sl1.Add(ld1);

            Assign a1 = new Assign();
            a1.lval = name;

            StringLiteral s1 = new StringLiteral();
            s1.value = " Joe!";

            a1.rval = s1;

            sl1.Add(a1);

            Assign a2 = new Assign();
            StringLiteral s2 = new StringLiteral();
            s2.value = "Hi!";

            TmpStringReg tsr0 = new TmpStringReg();
            tsr0.number = 0;

            a2.lval = tsr0;
            a2.rval = s2;

            sl1.Add(a2);

            Assign a3 = new Assign();
            TmpStringReg tsr1 = new TmpStringReg();
            tsr1.number = 1;

            BinaryCat bc1 = new BinaryCat();
            bc1.a = tsr0;
            bc1.b = name;

            a3.lval = tsr1;
            a3.rval = bc1;

            sl1.Add(a3);

            AssignCat a4 = new AssignCat();
            a4.lval = tsr1;
            StringLiteral s3 = new StringLiteral();
            s3.value = "\n";

            a4.rval = s3;

            sl1.Add(a4);

            CallStmt cs1 = new CallStmt();
            Call c1 = new Call();
            c1.func = "print";
            c1.args = tsr1;
            cs1.call = c1;
            sl1.Add(cs1);

            StringWriter sw = new StringWriter();
            PirateWriter pv = new PirateWriter(sw);

            DynamicVisitor.accept(p, pv);

            return sw.ToString();
        }
    static void sqlite3Insert(
    Parse pParse,        /* Parser context */
    SrcList pTabList,    /* Name of table into which we are inserting */
    ExprList pList,      /* List of values to be inserted */
    Select pSelect,      /* A SELECT statement to use as the data source */
    IdList pColumn,      /* Column names corresponding to IDLIST. */
    int onError        /* How to handle constraint errors */
    )
    {
      sqlite3 db;           /* The main database structure */
      Table pTab;           /* The table to insert into.  aka TABLE */
      string zTab;          /* Name of the table into which we are inserting */
      string zDb;           /* Name of the database holding this table */
      int i = 0;
      int j = 0;
      int idx = 0;            /* Loop counters */
      Vdbe v;               /* Generate code into this virtual machine */
      Index pIdx;           /* For looping over indices of the table */
      int nColumn;          /* Number of columns in the data */
      int nHidden = 0;      /* Number of hidden columns if TABLE is virtual */
      int baseCur = 0;      /* VDBE VdbeCursor number for pTab */
      int keyColumn = -1;   /* Column that is the INTEGER PRIMARY KEY */
      int endOfLoop = 0;      /* Label for the end of the insertion loop */
      bool useTempTable = false; /* Store SELECT results in intermediate table */
      int srcTab = 0;       /* Data comes from this temporary cursor if >=0 */
      int addrInsTop = 0;   /* Jump to label "D" */
      int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
      int addrSelect = 0;   /* Address of coroutine that implements the SELECT */
      SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
      int iDb;              /* Index of database holding TABLE */
      Db pDb;               /* The database containing table being inserted into */
      bool appendFlag = false;   /* True if the insert is likely to be an append */

      /* Register allocations */
      int regFromSelect = 0;  /* Base register for data coming from SELECT */
      int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
      int regRowCount = 0;  /* Memory cell used for the row counter */
      int regIns;           /* Block of regs holding rowid+data being inserted */
      int regRowid;         /* registers holding insert rowid */
      int regData;          /* register holding first column to insert */
      int regEof = 0;       /* Register recording end of SELECT data */
      int[] aRegIdx = null; /* One register allocated to each index */


#if !SQLITE_OMIT_TRIGGER
      bool isView = false;        /* True if attempting to insert into a view */
      Trigger pTrigger;           /* List of triggers on pTab, if required */
      int tmask = 0;              /* Mask of trigger times */
#endif

      db = pParse.db;
      dest = new SelectDest();// memset( &dest, 0, sizeof( dest ) );

      if ( pParse.nErr != 0 /*|| db.mallocFailed != 0 */ )
      {
        goto insert_cleanup;
      }

      /* Locate the table into which we will be inserting new information.
      */
      Debug.Assert( pTabList.nSrc == 1 );
      zTab = pTabList.a[0].zName;
      if ( NEVER( zTab == null ) )
        goto insert_cleanup;
      pTab = sqlite3SrcListLookup( pParse, pTabList );
      if ( pTab == null )
      {
        goto insert_cleanup;
      }
      iDb = sqlite3SchemaToIndex( db, pTab.pSchema );
      Debug.Assert( iDb < db.nDb );
      pDb = db.aDb[iDb];
      zDb = pDb.zName;
#if NO_SQLITE_OMIT_AUTHORIZATION //#if !SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab.zName, 0, zDb) ){
goto insert_cleanup;
}
#endif
      /* Figure out if we have any triggers and if the table being
** inserted into is a view
*/
#if !SQLITE_OMIT_TRIGGER
      pTrigger = sqlite3TriggersExist( pParse, pTab, TK_INSERT, null, out tmask );
      isView = pTab.pSelect != null;
#else
      Trigger pTrigger = null;  //# define pTrigger 0
      int tmask = 0;            //# define tmask 0
      bool isView = false;
#endif
#if  SQLITE_OMIT_VIEW
//# undef isView
isView = false;
#endif
#if !SQLITE_OMIT_TRIGGER
      Debug.Assert( ( pTrigger != null && tmask != 0 ) || ( pTrigger == null && tmask == 0 ) );
#endif

#if !SQLITE_OMIT_VIEW
      /* If pTab is really a view, make sure it has been initialized.
      ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
      ** module table).
      */
      if ( sqlite3ViewGetColumnNames( pParse, pTab ) != -0 )
      {
        goto insert_cleanup;
      }
#endif

      /* Ensure that:
      *  (a) the table is not read-only, 
      *  (b) that if it is a view then ON INSERT triggers exist
      */
      if ( sqlite3IsReadOnly( pParse, pTab, tmask ) )
      {
        goto insert_cleanup;
      }

      /* Allocate a VDBE
      */
      v = sqlite3GetVdbe( pParse );
      if ( v == null )
        goto insert_cleanup;
      if ( pParse.nested == 0 )
        sqlite3VdbeCountChanges( v );
      sqlite3BeginWriteOperation( pParse, ( pSelect != null || pTrigger != null ) ? 1 : 0, iDb );

#if !SQLITE_OMIT_XFER_OPT
      /* If the statement is of the form
**
**       INSERT INTO <table1> SELECT * FROM <table2>;
**
** Then special optimizations can be applied that make the transfer
** very fast and which reduce fragmentation of indices.
**
** This is the 2nd template.
*/
      if ( pColumn == null && xferOptimization( pParse, pTab, pSelect, onError, iDb ) != 0 )
      {
        Debug.Assert( null == pTrigger );
        Debug.Assert( pList == null );
        goto insert_end;
      }
#endif // * SQLITE_OMIT_XFER_OPT */

      /* If this is an AUTOINCREMENT table, look up the sequence number in the
** sqlite_sequence table and store it in memory cell regAutoinc.
*/
      regAutoinc = autoIncBegin( pParse, iDb, pTab );

      /* Figure out how many columns of data are supplied.  If the data
      ** is coming from a SELECT statement, then generate a co-routine that
      ** produces a single row of the SELECT on each invocation.  The
      ** co-routine is the common header to the 3rd and 4th templates.
      */
      if ( pSelect != null )
      {
        /* Data is coming from a SELECT.  Generate code to implement that SELECT
        ** as a co-routine.  The code is common to both the 3rd and 4th
        ** templates:
        **
        **         EOF <- 0
        **         X <- A
        **         goto B
        **      A: setup for the SELECT
        **         loop over the tables in the SELECT
        **           load value into register R..R+n
        **           yield X
        **         end loop
        **         cleanup after the SELECT
        **         EOF <- 1
        **         yield X
        **         halt-error
        **
        ** On each invocation of the co-routine, it puts a single row of the
        ** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
        ** (These output registers are allocated by sqlite3Select().)  When
        ** the SELECT completes, it sets the EOF flag stored in regEof.
        */
        int rc = 0, j1;

        regEof = ++pParse.nMem;
        sqlite3VdbeAddOp2( v, OP_Integer, 0, regEof );      /* EOF <- 0 */
#if SQLITE_DEBUG
        VdbeComment( v, "SELECT eof flag" );
#endif
        sqlite3SelectDestInit( dest, SRT_Coroutine, ++pParse.nMem );
        addrSelect = sqlite3VdbeCurrentAddr( v ) + 2;
        sqlite3VdbeAddOp2( v, OP_Integer, addrSelect - 1, dest.iParm );
        j1 = sqlite3VdbeAddOp2( v, OP_Goto, 0, 0 );
#if SQLITE_DEBUG
        VdbeComment( v, "Jump over SELECT coroutine" );
#endif
        /* Resolve the expressions in the SELECT statement and execute it. */
        rc = sqlite3Select( pParse, pSelect, ref dest );
        Debug.Assert( pParse.nErr == 0 || rc != 0 );
        if ( rc != 0 || NEVER( pParse.nErr != 0 ) /*|| db.mallocFailed != 0 */ )
        {
          goto insert_cleanup;
        }
        sqlite3VdbeAddOp2( v, OP_Integer, 1, regEof );         /* EOF <- 1 */
        sqlite3VdbeAddOp1( v, OP_Yield, dest.iParm );   /* yield X */
        sqlite3VdbeAddOp2( v, OP_Halt, SQLITE_INTERNAL, OE_Abort );
#if SQLITE_DEBUG
        VdbeComment( v, "End of SELECT coroutine" );
#endif
        sqlite3VdbeJumpHere( v, j1 );                          /* label B: */

        regFromSelect = dest.iMem;
        Debug.Assert( pSelect.pEList != null );
        nColumn = pSelect.pEList.nExpr;
        Debug.Assert( dest.nMem == nColumn );

        /* Set useTempTable to TRUE if the result of the SELECT statement
        ** should be written into a temporary table (template 4).  Set to
        ** FALSE if each* row of the SELECT can be written directly into
        ** the destination table (template 3).
        **
        ** A temp table must be used if the table being updated is also one
        ** of the tables being read by the SELECT statement.  Also use a
        ** temp table in the case of row triggers.
        */
        if ( pTrigger != null || readsTable( pParse, addrSelect, iDb, pTab ) )
        {
          useTempTable = true;
        }

        if ( useTempTable )
        {
          /* Invoke the coroutine to extract information from the SELECT
          ** and add it to a transient table srcTab.  The code generated
          ** here is from the 4th template:
          **
          **      B: open temp table
          **      L: yield X
          **         if EOF goto M
          **         insert row from R..R+n into temp table
          **         goto L
          **      M: ...
          */
          int regRec;      /* Register to hold packed record */
          int regTempRowid;    /* Register to hold temp table ROWID */
          int addrTop;     /* Label "L" */
          int addrIf;      /* Address of jump to M */

          srcTab = pParse.nTab++;
          regRec = sqlite3GetTempReg( pParse );
          regTempRowid = sqlite3GetTempReg( pParse );
          sqlite3VdbeAddOp2( v, OP_OpenEphemeral, srcTab, nColumn );
          addrTop = sqlite3VdbeAddOp1( v, OP_Yield, dest.iParm );
          addrIf = sqlite3VdbeAddOp1( v, OP_If, regEof );
          sqlite3VdbeAddOp3( v, OP_MakeRecord, regFromSelect, nColumn, regRec );
          sqlite3VdbeAddOp2( v, OP_NewRowid, srcTab, regTempRowid );
          sqlite3VdbeAddOp3( v, OP_Insert, srcTab, regRec, regTempRowid );
          sqlite3VdbeAddOp2( v, OP_Goto, 0, addrTop );
          sqlite3VdbeJumpHere( v, addrIf );
          sqlite3ReleaseTempReg( pParse, regRec );
          sqlite3ReleaseTempReg( pParse, regTempRowid );
        }
      }
      else
      {
        /* This is the case if the data for the INSERT is coming from a VALUES
        ** clause
        */
        NameContext sNC;
        sNC = new NameContext();// memset( &sNC, 0, sNC ).Length;
        sNC.pParse = pParse;
        srcTab = -1;
        Debug.Assert( !useTempTable );
        nColumn = pList != null ? pList.nExpr : 0;
        for ( i = 0; i < nColumn; i++ )
        {
          if ( sqlite3ResolveExprNames( sNC, ref pList.a[i].pExpr ) != 0 )
          {
            goto insert_cleanup;
          }
        }
      }

      /* Make sure the number of columns in the source data matches the number
      ** of columns to be inserted into the table.
      */
      if ( IsVirtual( pTab ) )
      {
        for ( i = 0; i < pTab.nCol; i++ )
        {
          nHidden += ( IsHiddenColumn( pTab.aCol[i] ) ? 1 : 0 );
        }
      }
      if ( pColumn == null && nColumn != 0 && nColumn != ( pTab.nCol - nHidden ) )
      {
        sqlite3ErrorMsg( pParse,
        "table %S has %d columns but %d values were supplied",
        pTabList, 0, pTab.nCol - nHidden, nColumn );
        goto insert_cleanup;
      }
      if ( pColumn != null && nColumn != pColumn.nId )
      {
        sqlite3ErrorMsg( pParse, "%d values for %d columns", nColumn, pColumn.nId );
        goto insert_cleanup;
      }

      /* If the INSERT statement included an IDLIST term, then make sure
      ** all elements of the IDLIST really are columns of the table and
      ** remember the column indices.
      **
      ** If the table has an INTEGER PRIMARY KEY column and that column
      ** is named in the IDLIST, then record in the keyColumn variable
      ** the index into IDLIST of the primary key column.  keyColumn is
      ** the index of the primary key as it appears in IDLIST, not as
      ** is appears in the original table.  (The index of the primary
      ** key in the original table is pTab.iPKey.)
      */
      if ( pColumn != null )
      {
        for ( i = 0; i < pColumn.nId; i++ )
        {
          pColumn.a[i].idx = -1;
        }
        for ( i = 0; i < pColumn.nId; i++ )
        {
          for ( j = 0; j < pTab.nCol; j++ )
          {
            if ( pColumn.a[i].zName.Equals( pTab.aCol[j].zName ,StringComparison.InvariantCultureIgnoreCase )  )
            {
              pColumn.a[i].idx = j;
              if ( j == pTab.iPKey )
              {
                keyColumn = i;
              }
              break;
            }
          }
          if ( j >= pTab.nCol )
          {
            if ( sqlite3IsRowid( pColumn.a[i].zName ) )
            {
              keyColumn = i;
            }
            else
            {
              sqlite3ErrorMsg( pParse, "table %S has no column named %s",
              pTabList, 0, pColumn.a[i].zName );
              pParse.checkSchema = 1;
              goto insert_cleanup;
            }
          }
        }
      }

      /* If there is no IDLIST term but the table has an integer primary
      ** key, the set the keyColumn variable to the primary key column index
      ** in the original table definition.
      */
      if ( pColumn == null && nColumn > 0 )
      {
        keyColumn = pTab.iPKey;
      }

      /* Initialize the count of rows to be inserted
      */
      if ( ( db.flags & SQLITE_CountRows ) != 0 )
      {
        regRowCount = ++pParse.nMem;
        sqlite3VdbeAddOp2( v, OP_Integer, 0, regRowCount );
      }

      /* If this is not a view, open the table and and all indices */
      if ( !isView )
      {
        int nIdx;

        baseCur = pParse.nTab;
        nIdx = sqlite3OpenTableAndIndices( pParse, pTab, baseCur, OP_OpenWrite );
        aRegIdx = new int[nIdx + 1];// sqlite3DbMallocRaw( db, sizeof( int ) * ( nIdx + 1 ) );
        if ( aRegIdx == null )
        {
          goto insert_cleanup;
        }
        for ( i = 0; i < nIdx; i++ )
        {
          aRegIdx[i] = ++pParse.nMem;
        }
      }

      /* This is the top of the main insertion loop */
      if ( useTempTable )
      {
        /* This block codes the top of loop only.  The complete loop is the
        ** following pseudocode (template 4):
        **
        **         rewind temp table
        **      C: loop over rows of intermediate table
        **           transfer values form intermediate table into <table>
        **         end loop
        **      D: ...
        */
        addrInsTop = sqlite3VdbeAddOp1( v, OP_Rewind, srcTab );
        addrCont = sqlite3VdbeCurrentAddr( v );
      }
      else if ( pSelect != null )
      {
        /* This block codes the top of loop only.  The complete loop is the
        ** following pseudocode (template 3):
        **
        **      C: yield X
        **         if EOF goto D
        **         insert the select result into <table> from R..R+n
        **         goto C
        **      D: ...
        */
        addrCont = sqlite3VdbeAddOp1( v, OP_Yield, dest.iParm );
        addrInsTop = sqlite3VdbeAddOp1( v, OP_If, regEof );
      }

      /* Allocate registers for holding the rowid of the new row,
      ** the content of the new row, and the assemblied row record.
      */
      regRowid = regIns = pParse.nMem + 1;
      pParse.nMem += pTab.nCol + 1;
      if ( IsVirtual( pTab ) )
      {
        regRowid++;
        pParse.nMem++;
      }
      regData = regRowid + 1;

      /* Run the BEFORE and INSTEAD OF triggers, if there are any
      */
      endOfLoop = sqlite3VdbeMakeLabel( v );
#if !SQLITE_OMIT_TRIGGER
      if ( ( tmask & TRIGGER_BEFORE ) != 0 )
      {
        int regCols = sqlite3GetTempRange( pParse, pTab.nCol + 1 );

        /* build the NEW.* reference row.  Note that if there is an INTEGER
        ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
        ** translated into a unique ID for the row.  But on a BEFORE trigger,
        ** we do not know what the unique ID will be (because the insert has
        ** not happened yet) so we substitute a rowid of -1
        */
        if ( keyColumn < 0 )
        {
          sqlite3VdbeAddOp2( v, OP_Integer, -1, regCols );
        }
        else
        {
          int j1;
          if ( useTempTable )
          {
            sqlite3VdbeAddOp3( v, OP_Column, srcTab, keyColumn, regCols );
          }
          else
          {
            Debug.Assert( pSelect == null );  /* Otherwise useTempTable is true */
            sqlite3ExprCode( pParse, pList.a[keyColumn].pExpr, regCols );
          }
          j1 = sqlite3VdbeAddOp1( v, OP_NotNull, regCols );
          sqlite3VdbeAddOp2( v, OP_Integer, -1, regCols );
          sqlite3VdbeJumpHere( v, j1 );
          sqlite3VdbeAddOp1( v, OP_MustBeInt, regCols );
        }
        /* Cannot have triggers on a virtual table. If it were possible,
        ** this block would have to account for hidden column.
        */
        Debug.Assert( !IsVirtual( pTab ) );
        /* Create the new column data
        */
        for ( i = 0; i < pTab.nCol; i++ )
        {
          if ( pColumn == null )
          {
            j = i;
          }
          else
          {
            for ( j = 0; j < pColumn.nId; j++ )
            {
              if ( pColumn.a[j].idx == i )
                break;
            }
          }
          if ( ( !useTempTable && null == pList ) || ( pColumn != null && j >= pColumn.nId ) )
          {
            sqlite3ExprCode( pParse, pTab.aCol[i].pDflt, regCols + i + 1 );
          }
          else if ( useTempTable )
          {
            sqlite3VdbeAddOp3( v, OP_Column, srcTab, j, regCols + i + 1 );
          }
          else
          {
            Debug.Assert( pSelect == null ); /* Otherwise useTempTable is true */
            sqlite3ExprCodeAndCache( pParse, pList.a[j].pExpr, regCols + i + 1 );
          }
        }

        /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
        ** do not attempt any conversions before assembling the record.
        ** If this is a real table, attempt conversions as required by the
        ** table column affinities.
        */
        if ( !isView )
        {
          sqlite3VdbeAddOp2( v, OP_Affinity, regCols + 1, pTab.nCol );
          sqlite3TableAffinityStr( v, pTab );
        }

        /* Fire BEFORE or INSTEAD OF triggers */
        sqlite3CodeRowTrigger( pParse, pTrigger, TK_INSERT, null, TRIGGER_BEFORE,
            pTab, regCols - pTab.nCol - 1, onError, endOfLoop );

        sqlite3ReleaseTempRange( pParse, regCols, pTab.nCol + 1 );
      }
#endif

      /* Push the record number for the new entry onto the stack.  The
** record number is a randomly generate integer created by NewRowid
** except when the table has an INTEGER PRIMARY KEY column, in which
** case the record number is the same as that column.
*/
      if ( !isView )
      {
        if ( IsVirtual( pTab ) )
        {
          /* The row that the VUpdate opcode will delete: none */
          sqlite3VdbeAddOp2( v, OP_Null, 0, regIns );
        }
        if ( keyColumn >= 0 )
        {
          if ( useTempTable )
          {
            sqlite3VdbeAddOp3( v, OP_Column, srcTab, keyColumn, regRowid );
          }
          else if ( pSelect != null )
          {
            sqlite3VdbeAddOp2( v, OP_SCopy, regFromSelect + keyColumn, regRowid );
          }
          else
          {
            VdbeOp pOp;
            sqlite3ExprCode( pParse, pList.a[keyColumn].pExpr, regRowid );
            pOp = sqlite3VdbeGetOp( v, -1 );
            if ( ALWAYS( pOp != null ) && pOp.opcode == OP_Null && !IsVirtual( pTab ) )
            {
              appendFlag = true;
              pOp.opcode = OP_NewRowid;
              pOp.p1 = baseCur;
              pOp.p2 = regRowid;
              pOp.p3 = regAutoinc;
            }
          }
          /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
          ** to generate a unique primary key value.
          */
          if ( !appendFlag )
          {
            int j1;
            if ( !IsVirtual( pTab ) )
            {
              j1 = sqlite3VdbeAddOp1( v, OP_NotNull, regRowid );
              sqlite3VdbeAddOp3( v, OP_NewRowid, baseCur, regRowid, regAutoinc );
              sqlite3VdbeJumpHere( v, j1 );
            }
            else
            {
              j1 = sqlite3VdbeCurrentAddr( v );
              sqlite3VdbeAddOp2( v, OP_IsNull, regRowid, j1 + 2 );
            }
            sqlite3VdbeAddOp1( v, OP_MustBeInt, regRowid );
          }
        }
        else if ( IsVirtual( pTab ) )
        {
          sqlite3VdbeAddOp2( v, OP_Null, 0, regRowid );
        }
        else
        {
          sqlite3VdbeAddOp3( v, OP_NewRowid, baseCur, regRowid, regAutoinc );
          appendFlag = true;
        }
        autoIncStep( pParse, regAutoinc, regRowid );

        /* Push onto the stack, data for all columns of the new entry, beginning
        ** with the first column.
        */
        nHidden = 0;
        for ( i = 0; i < pTab.nCol; i++ )
        {
          int iRegStore = regRowid + 1 + i;
          if ( i == pTab.iPKey )
          {
            /* The value of the INTEGER PRIMARY KEY column is always a NULL.
            ** Whenever this column is read, the record number will be substituted
            ** in its place.  So will fill this column with a NULL to avoid
            ** taking up data space with information that will never be used. */
            sqlite3VdbeAddOp2( v, OP_Null, 0, iRegStore );
            continue;
          }
          if ( pColumn == null )
          {
            if ( IsHiddenColumn( pTab.aCol[i] ) )
            {
              Debug.Assert( IsVirtual( pTab ) );
              j = -1;
              nHidden++;
            }
            else
            {
              j = i - nHidden;
            }
          }
          else
          {
            for ( j = 0; j < pColumn.nId; j++ )
            {
              if ( pColumn.a[j].idx == i )
                break;
            }
          }
          if ( j < 0 || nColumn == 0 || ( pColumn != null && j >= pColumn.nId ) )
          {
            sqlite3ExprCode( pParse, pTab.aCol[i].pDflt, iRegStore );
          }
          else if ( useTempTable )
          {
            sqlite3VdbeAddOp3( v, OP_Column, srcTab, j, iRegStore );
          }
          else if ( pSelect != null )
          {
            sqlite3VdbeAddOp2( v, OP_SCopy, regFromSelect + j, iRegStore );
          }
          else
          {
            sqlite3ExprCode( pParse, pList.a[j].pExpr, iRegStore );
          }
        }

        /* Generate code to check constraints and generate index keys and
        ** do the insertion.
        */
#if !SQLITE_OMIT_VIRTUALTABLE
        if ( IsVirtual( pTab ) )
        {
          VTable pVTab = sqlite3GetVTable( db, pTab );
          sqlite3VtabMakeWritable( pParse, pTab );
          sqlite3VdbeAddOp4( v, OP_VUpdate, 1, pTab.nCol + 2, regIns, pVTab, P4_VTAB );
          sqlite3VdbeChangeP5( v, (byte)( onError == OE_Default ? OE_Abort : onError ) );
          sqlite3MayAbort( pParse );
        }
        else
#endif
        {
          int isReplace = 0;    /* Set to true if constraints may cause a replace */
          sqlite3GenerateConstraintChecks( pParse, pTab, baseCur, regIns, aRegIdx,
            keyColumn >= 0 ? 1 : 0, false, onError, endOfLoop, out isReplace
          );
          sqlite3FkCheck( pParse, pTab, 0, regIns );
          sqlite3CompleteInsertion(
         pParse, pTab, baseCur, regIns, aRegIdx, false, appendFlag, isReplace == 0
          );
        }
      }

      /* Update the count of rows that are inserted
      */
      if ( ( db.flags & SQLITE_CountRows ) != 0 )
      {
        sqlite3VdbeAddOp2( v, OP_AddImm, regRowCount, 1 );
      }

#if !SQLITE_OMIT_TRIGGER
      if ( pTrigger != null )
      {
        /* Code AFTER triggers */
        sqlite3CodeRowTrigger( pParse, pTrigger, TK_INSERT, null, TRIGGER_AFTER,
            pTab, regData - 2 - pTab.nCol, onError, endOfLoop );
      }
#endif

      /* The bottom of the main insertion loop, if the data source
** is a SELECT statement.
*/
      sqlite3VdbeResolveLabel( v, endOfLoop );
      if ( useTempTable )
      {
        sqlite3VdbeAddOp2( v, OP_Next, srcTab, addrCont );
        sqlite3VdbeJumpHere( v, addrInsTop );
        sqlite3VdbeAddOp1( v, OP_Close, srcTab );
      }
      else if ( pSelect != null )
      {
        sqlite3VdbeAddOp2( v, OP_Goto, 0, addrCont );
        sqlite3VdbeJumpHere( v, addrInsTop );
      }

      if ( !IsVirtual( pTab ) && !isView )
      {
        /* Close all tables opened */
        sqlite3VdbeAddOp1( v, OP_Close, baseCur );
        for ( idx = 1, pIdx = pTab.pIndex; pIdx != null; pIdx = pIdx.pNext, idx++ )
        {
          sqlite3VdbeAddOp1( v, OP_Close, idx + baseCur );
        }
      }

insert_end:
      /* Update the sqlite_sequence table by storing the content of the
      ** maximum rowid counter values recorded while inserting into
      ** autoincrement tables.
      */
      if ( pParse.nested == 0 && pParse.pTriggerTab == null )
      {
        sqlite3AutoincrementEnd( pParse );
      }

      /*
      ** Return the number of rows inserted. If this routine is
      ** generating code because of a call to sqlite3NestedParse(), do not
      ** invoke the callback function.
      */
      if ( ( db.flags & SQLITE_CountRows ) != 0 && 0 == pParse.nested && null == pParse.pTriggerTab )
      {
        sqlite3VdbeAddOp2( v, OP_ResultRow, regRowCount, 1 );
        sqlite3VdbeSetNumCols( v, 1 );
        sqlite3VdbeSetColName( v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC );
      }

insert_cleanup:
      sqlite3SrcListDelete( db, ref pTabList );
      sqlite3ExprListDelete( db, ref pList );
      sqlite3SelectDelete( db, ref pSelect );
      sqlite3IdListDelete( db, ref pColumn );
      sqlite3DbFree( db, ref aRegIdx );
    }
 static void sqlite3Insert( Parse pParse, SrcList pTabList, int null_3, Select pSelect, IdList pColumn, int onError )
 {
   sqlite3Insert( pParse, pTabList, null, pSelect, pColumn, onError );
 }
Beispiel #13
0
 void IdentifierList(out IdList list)
 {
     list = new IdList(); string name;
     Identifier(out name);
     list.Add(name);
     while (la.kind == 14) {
     Get();
     Identifier(out name);
     list.Add(name);
     }
 }
Beispiel #14
0
 // OVERLOADS, so I don't need to rewrite parse.c
 public static TriggerStep TriggerInsertStep(Context ctx, Token tableName, IdList column, int null_4, int null_5, OE orconf)
 {
     return(TriggerInsertStep(ctx, tableName, column, null, null, orconf));
 }
Beispiel #15
0
		/*
		** Build a trigger step out of an INSERT statement.  Return a pointer
		** to the new trigger step.
		**
		** The parser calls this routine when it sees an INSERT inside the
		** body of a trigger.
		*/

		// OVERLOADS, so I don't need to rewrite parse.c
		private static TriggerStep sqlite3TriggerInsertStep(sqlite3 db, Token pTableName, IdList pColumn, int null_4, int null_5, u8 orconf)
		{
			return sqlite3TriggerInsertStep(db, pTableName, pColumn, null, null, orconf);
		}
Beispiel #16
0
 void StateIdentifierList(out IdList list)
 {
     list = null;
     if (la.kind == 1) {
     IdentifierList(out list);
     } else if (la.kind == 31) {
     Get();
     list = new IdList(true);
     } else if (la.kind == 32) {
     Get();
     list = new IdList("0");
     } else if (la.kind == 33) {
     Get();
     list = new IdList("1");
     } else SynErr(43);
 }
Beispiel #17
0
 public static TriggerStep TriggerInsertStep(Context ctx, Token tableName, IdList column, ExprList list, int null_5, OE orconf) { return TriggerInsertStep(ctx, tableName, column, list, null, orconf); }
 static void sqlite3Insert( Parse pParse, SrcList pTabList, ExprList pList, int null_4, IdList pColumn, int onError )
 {
   sqlite3Insert( pParse, pTabList, pList, null, pColumn, onError );
 }
Beispiel #19
0
 public static TriggerStep TriggerInsertStep(Context ctx, Token tableName, IdList column, int null_4, Select select, OE orconf) { return TriggerInsertStep(ctx, tableName, column, null, select, orconf); }
Beispiel #20
0
 static IdList sqlite3IdListDup( sqlite3 db, IdList p )
 {
   IdList pNew;
   int i;
   if ( p == null )
     return null;
   pNew = new IdList();//sqlite3DbMallocRaw(db, sizeof(*pNew) );
   if ( pNew == null )
     return null;
   pNew.nId = pNew.nAlloc = p.nId;
   pNew.a = new IdList_item[p.nId];//sqlite3DbMallocRaw(db, p.nId*sizeof(p.a[0]) );
   if ( pNew.a == null )
   {
     sqlite3DbFree( db, ref pNew );
     return null;
   }
   for ( i = 0; i < p.nId; i++ )
   {
     pNew.a[i] = new IdList_item();
     IdList_item pNewItem = pNew.a[i];
     IdList_item pOldItem = p.a[i];
     pNewItem.zName = pOldItem.zName;// sqlite3DbStrDup(db, pOldItem.zName);
     pNewItem.idx = pOldItem.idx;
   }
   return pNew;
 }
Beispiel #21
0
 public static TriggerStep TriggerInsertStep(Context ctx, Token tableName, IdList column, ExprList list, Select select, OE orconf)
 {
     Debug.Assert(list == null || select == null);
     Debug.Assert(list != null || select != null || ctx.MallocFailed);
     TriggerStep triggerStep = TriggerStepAllocate(ctx, TK.INSERT, tableName);
     if (triggerStep != null)
     {
         triggerStep.Select = Select.Dup(ctx, select, E.EXPRDUP_REDUCE);
         triggerStep.IdList = column;
         triggerStep.ExprList = Expr.ListDup(ctx, list, E.EXPRDUP_REDUCE);
         triggerStep.Orconf = orconf;
     }
     else
         Expr.IdListDelete(ctx, ref column);
     Expr.ListDelete(ctx, ref list);
     Select.Delete(ctx, ref select);
     return triggerStep;
 }
Beispiel #22
0
        static string Example4()
        {
            StmtList sl1 = new StmtList();

            Sub foo = new Sub("foo", sl1);

            Pirate p = new Pirate();
            p.Add(foo);

            ParamDecl pd1 = new ParamDecl();

            pd1.type = new IntType();

            IdList idl1 = new IdList();
            NamedReg n = new NamedReg();
            n.name = "n";
            idl1.Add(n);

            pd1.id_list = idl1;
            sl1.Add(pd1);

            ParamDecl pd2 = new ParamDecl();

            pd2.type = new StringType();

            IdList idl2 = new IdList();
            NamedReg message = new NamedReg();
            message.name = "message";
            idl2.Add(message);

            pd2.id_list = idl2;
            sl1.Add(pd2);

            StringWriter sw = new StringWriter();
            PirateWriter pv = new PirateWriter(sw);

            DynamicVisitor.accept(p, pv);

            return sw.ToString();
        }
Beispiel #23
0
 static bool CheckColumnOverlap(IdList idList, ExprList eList)
 {
     if (idList == null || C._NEVER(eList == null)) return true;
     for (int e = 0; e < eList.Exprs; e++)
         if (Expr.IdListIndex(idList, eList.Ids[e].Name) >= 0) return true;
     return false;
 }
Beispiel #24
0
        static string Example2()
        {
            NamedReg a = new NamedReg("a");
            NamedReg b = new NamedReg("b");
            NamedReg c = new NamedReg("c");
            NamedReg det = new NamedReg("det");

            IdList rl1 = new IdList();
            rl1.Add(a);
            rl1.Add(b);
            rl1.Add(c);
            rl1.Add(det);

            LocalDecl ld1 = new LocalDecl(new NumType(), rl1);

            IntLiteral il3 = new IntLiteral(2);
            Assign a12 = new Assign(a, il3);

            IntLiteral il4 = new IntLiteral(-3);
            Assign a13 = new Assign(b, il4);

            IntLiteral il5 = new IntLiteral(-2);
            Assign a14 = new Assign(c, il5);

            UnaryNeg un1 = new UnaryNeg(b);
            TmpNumReg tnr0 = new TmpNumReg(0);
            Assign a1 = new Assign(tnr0, un1);

            TmpNumReg tnr1 = new TmpNumReg(1);
            BinaryMul bm1 = new BinaryMul(b, b);
            Assign a2 = new Assign(tnr1, bm1);

            TmpNumReg tnr2 = new TmpNumReg(2);
            IntLiteral il1 = new IntLiteral(4);
            BinaryMul bm2 = new BinaryMul(il1, a);
            Assign a3 = new Assign(tnr2, bm2);

            BinaryMul bm3 = new BinaryMul(tnr2, c);
            Assign a4 = new Assign(tnr2, bm3);

            TmpNumReg tnr3 = new TmpNumReg(3);
            IntLiteral il2 = new IntLiteral(2);
            BinaryMul bm4 = new BinaryMul(il2, a);
            Assign a5 = new Assign(tnr3, bm4);

            BinarySub bs1 = new BinarySub(tnr1, tnr2);
            Assign a6 = new Assign(det, bs1);

            TmpNumReg tnr4 = new TmpNumReg(4);
            Call sqrt = new Call("sqrt", det);
            Assign a7 = new Assign(tnr4, sqrt);

            NamedReg x1 = new NamedReg("x1");
            NamedReg x2 = new NamedReg("x2");

            IdList rl2 = new IdList();
            rl2.Add(x1);
            rl2.Add(x2);

            LocalDecl ld2 = new LocalDecl(new NumType(), rl2);

            BinaryAdd ba1 = new BinaryAdd(tnr0, tnr4);
            Assign a8 = new Assign(x1, ba1);

            BinaryDiv bd1 = new BinaryDiv(x1, tnr3);
            Assign a9 = new Assign(x1, bd1);

            BinarySub bs2 = new BinarySub(tnr0, tnr4);
            Assign a10 = new Assign(x2, bs2);

            AssignDiv a11 = new AssignDiv(x2, tnr3);

            StringLiteral s1 = new StringLiteral("Answers to ABC formula are:\n");
            Call c1 = new Call("print", s1);
            CallStmt print1 = new CallStmt(c1);

            StringLiteral s2 = new StringLiteral("x1 = ");
            Call c2 = new Call("print", s2);
            CallStmt print2 = new CallStmt(c2);

            Call c3 = new Call("print", x1);
            CallStmt print3 = new CallStmt(c3);

            StringLiteral s4 = new StringLiteral("\nx2 = ");
            Call c4 = new Call("print", s4);
            CallStmt print4 = new CallStmt(c4);

            Call c5 = new Call("print", x2);
            CallStmt print5 = new CallStmt(c5);

            StringLiteral s6 = new StringLiteral("\n");
            Call c6 = new Call("print", s6);
            CallStmt print6 = new CallStmt(c6);

            StmtList sl1 = new StmtList();
            sl1.Add(ld1);
            sl1.Add(a12);
            sl1.Add(a13);
            sl1.Add(a14);
            sl1.Add(a1);
            sl1.Add(a2);
            sl1.Add(a3);
            sl1.Add(a4);
            sl1.Add(a5);
            sl1.Add(a6);
            sl1.Add(a7);
            sl1.Add(ld2);
            sl1.Add(a8);
            sl1.Add(a9);
            sl1.Add(a10);
            sl1.Add(a11);
            sl1.Add(print1);
            sl1.Add(print2);
            sl1.Add(print3);
            sl1.Add(print4);
            sl1.Add(print5);
            sl1.Add(print6);

            Sub foo = new Sub("foo", sl1);

            Pirate p = new Pirate();
            p.Add(foo);

            StringWriter sw = new StringWriter();
            PirateWriter pv = new PirateWriter(sw);

            DynamicVisitor.accept(p, pv);

            return sw.ToString();
        }
Beispiel #25
0
        public static void BeginTrigger(Parse parse, Token name1, Token name2, TK trTm, TK op, IdList columns, SrcList tableName, Expr when, bool isTemp, int noErr)
        {
            Context ctx = parse.Ctx; // The database connection
            Debug.Assert(name1 != null);   // pName1.z might be NULL, but not pName1 itself
            Debug.Assert(name2 != null);
            Debug.Assert(op == TK.INSERT || op == TK.UPDATE || op == TK.DELETE);
            Debug.Assert(op > 0 && op < (TK)0xff);
            Trigger trigger = null; // The new trigger

            int db; // The database to store the trigger in
            Token name = null; // The unqualified db name
            if (isTemp)
            {
                // If TEMP was specified, then the trigger name may not be qualified.
                if (name2.length > 0)
                {
                    parse.ErrorMsg("temporary trigger may not have qualified name");
                    goto trigger_cleanup;
                }
                db = 1;
                name = name1;
            }
            else
            {
                // Figure out the db that the the trigger will be created in
                db = parse.TwoPartName(name1, name2, ref name);
                if (db < 0)
                    goto trigger_cleanup;
            }
            if (tableName == null || ctx.MallocFailed)
                goto trigger_cleanup;

            // A long-standing parser bug is that this syntax was allowed:
            //    CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
            //                                                 ^^^^^^^^
            // To maintain backwards compatibility, ignore the database name on pTableName if we are reparsing our of SQLITE_MASTER.
            if (ctx.Init.Busy && db != 1)
            {
                C._tagfree(ctx, ref tableName.Ids[0].Database);
                tableName.Ids[0].Database = null;
            }

            // If the trigger name was unqualified, and the table is a temp table, then set iDb to 1 to create the trigger in the temporary database.
            // If sqlite3SrcListLookup() returns 0, indicating the table does not exist, the error is caught by the block below.
            //? if (tableName == null) goto trigger_cleanup;
            Table table = Delete.SrcListLookup(parse, tableName); // Table that the trigger fires off of
            if (ctx.Init.Busy == null && name2.length == 0 && table != null && table.Schema == ctx.DBs[1].Schema)
                db = 1;

            // Ensure the table name matches database name and that the table exists
            if (ctx.MallocFailed) goto trigger_cleanup;
            Debug.Assert(tableName.Srcs == 1);
            DbFixer sFix = new DbFixer(); // State vector for the DB fixer
            if (sFix.FixInit(parse, db, "trigger", name) && sFix.FixSrcList(tableName))
                goto trigger_cleanup;
            table = Delete.SrcListLookup(parse, tableName);
            if (table == null)
            {
                // The table does not exist.
                if (ctx.Init.DB == 1)
                {
                    // Ticket #3810.
                    // Normally, whenever a table is dropped, all associated triggers are dropped too.  But if a TEMP trigger is created on a non-TEMP table
                    // and the table is dropped by a different database connection, the trigger is not visible to the database connection that does the
                    // drop so the trigger cannot be dropped.  This results in an "orphaned trigger" - a trigger whose associated table is missing.
                    ctx.Init.OrphanTrigger = true;
                }
                goto trigger_cleanup;
            }
            if (E.IsVirtual(table))
            {
                parse.ErrorMsg("cannot create triggers on virtual tables");
                goto trigger_cleanup;
            }

            // Check that the trigger name is not reserved and that no trigger of the specified name exists
            string nameAsString = Parse.NameFromToken(ctx, name);
            if (nameAsString == null || parse.CheckObjectName(nameAsString) != RC.OK)
                goto trigger_cleanup;
            Debug.Assert(Btree.SchemaMutexHeld(ctx, db, null));
            if (ctx.DBs[db].Schema.TriggerHash.Find(nameAsString, nameAsString.Length, (Trigger)null) != null)
            {
                if (noErr == 0)
                    parse.ErrorMsg("trigger %T already exists", name);
                else
                {
                    Debug.Assert(!ctx.Init.Busy);
                    parse.CodeVerifySchema(db);
                }
                goto trigger_cleanup;
            }

            // Do not create a trigger on a system table
            if (table.Name.StartsWith("sqlite_", StringComparison.InvariantCultureIgnoreCase))
            {
                parse.ErrorMsg("cannot create trigger on system table");
                parse.Errs++;
                goto trigger_cleanup;
            }

            // INSTEAD of triggers are only for views and views only support INSTEAD of triggers.
            if (table.Select != null && trTm != TK.INSTEAD)
            {
                parse.ErrorMsg("cannot create %s trigger on view: %S", (trTm == TK.BEFORE ? "BEFORE" : "AFTER"), tableName, 0);
                goto trigger_cleanup;
            }
            if (table.Select == null && trTm == TK.INSTEAD)
            {
                parse.ErrorMsg("cannot create INSTEAD OF trigger on table: %S", tableName, 0);
                goto trigger_cleanup;
            }

#if !OMIT_AUTHORIZATION
            {
                int tabDb = Prepare.SchemaToIndex(ctx, table.Schema); // Index of the database holding pTab
                AUTH code = AUTH.CREATE_TRIGGER;
                string dbName = ctx.DBs[tabDb].Name;
                string dbTrigName = (isTemp ? ctx.DBs[1].Name : dbName);
                if (tabDb == 1 || isTemp) code = AUTH.CREATE_TEMP_TRIGGER;
                if (Auth.Check(parse, code, nameAsString, table.Name, dbTrigName) != 0 || Auth.Check(parse, AUTH.INSERT, E.SCHEMA_TABLE(tabDb), 0, dbName))
                    goto trigger_cleanup;
            }
#endif

            // INSTEAD OF triggers can only appear on views and BEFORE triggers cannot appear on views.  So we might as well translate every
            // INSTEAD OF trigger into a BEFORE trigger.  It simplifies code elsewhere.
            if (trTm == TK.INSTEAD)
                trTm = TK.BEFORE;

            // Build the Trigger object
            trigger = new Trigger(); //: (Trigger *)_tagalloc(db, sizeof(Trigger), true);
            if (trigger == null) goto trigger_cleanup;
            trigger.Name = name;
            trigger.Table = tableName.Ids[0].Name; //: _tagstrdup(ctx, tableName->Ids[0].Name);
            trigger.Schema = ctx.DBs[db].Schema;
            trigger.TabSchema = table.Schema;
            trigger.OP = op;
            trigger.TRtm = (trTm == TK.BEFORE ? TRIGGER.BEFORE : TRIGGER.AFTER);
            trigger.When = Expr.Dup(db, when, E.EXPRDUP_REDUCE);
            trigger.Columns = Expr.IdListDup(ctx, columns);
            Debug.Assert(parse.NewTrigger == null);
            parse.NewTrigger = trigger;

        trigger_cleanup:
            C._tagfree(ctx, ref name);
            Expr.SrcListDelete(ctx, ref tableName);
            Expr.IdListDelete(ctx, ref columns);
            Expr.Delete(ctx, ref when);
            if (parse.NewTrigger == null)
                DeleteTrigger(ctx, ref trigger);
            else
                Debug.Assert(parse.NewTrigger == trigger);
        }
Beispiel #26
0
 static TriggerStep sqlite3TriggerInsertStep( sqlite3 db, Token pTableName, IdList pColumn, ExprList pEList, int null_5, u8 orconf )
 {
   return sqlite3TriggerInsertStep( db, pTableName, pColumn, pEList, null, orconf );
 }
Beispiel #27
0
 /// <summary>
 /// Sets the PRE states of a state transition condition.
 /// </summary>
 /// <param name="names"></param>
 public void SetPreStates(IdList names)
 {
     StateIndexes.AddRange(Variable.Type.GetIndexesOfNames(names));
     PreWildcard = names.Wildcard;
 }
Beispiel #28
0
    static TriggerStep sqlite3TriggerInsertStep(
    sqlite3 db,        /* The database connection */
    Token pTableName,  /* Name of the table into which we insert */
    IdList pColumn,    /* List of columns in pTableName to insert into */
    ExprList pEList,   /* The VALUE clause: a list of values to be inserted */
    Select pSelect,    /* A SELECT statement that supplies values */
    u8 orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
    )
    {
      TriggerStep pTriggerStep;

      Debug.Assert( pEList == null || pSelect == null );
      Debug.Assert( pEList != null || pSelect != null /*|| db.mallocFailed != 0 */ );

      pTriggerStep = triggerStepAllocate( db, TK_INSERT, pTableName );
      //if ( pTriggerStep != null )
      //{
      pTriggerStep.pSelect = sqlite3SelectDup( db, pSelect, EXPRDUP_REDUCE );
      pTriggerStep.pIdList = pColumn;
      pTriggerStep.pExprList = sqlite3ExprListDup( db, pEList, EXPRDUP_REDUCE );
      pTriggerStep.orconf = orconf;
      //}
      //else
      //{
      //  sqlite3IdListDelete( db, ref pColumn );
      //}
      sqlite3ExprListDelete( db, ref pEList );
      sqlite3SelectDelete( db, ref pSelect );

      return pTriggerStep;
    }
Beispiel #29
0
 //-----------------------------------------------------------
 //<var-list>// <-- //<id-list>//
 //<paramList>// <-- //<id-List>
 public void Visit(IdList node, int i)
 {
     VisitChildren(node, i);
 }